home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Reference / the cmsp digests ('94-'97) / csmp digest Vol 3 No 067 < prev    next >
Internet Message Format  |  1997-05-06  |  136KB

  1. From: pottier@clipper.ens.fr (Francois Pottier)
  2. Subject: csmp-digest-v3-067
  3. Date: Mon, 14 Nov 1994 15:53:04 +0100 (MET)
  4.  
  5. C.S.M.P. Digest             Mon, 14 Nov 94       Volume 3 : Issue 67
  6.  
  7. Today's Topics:
  8.  
  9.         (Q) AppleScript & XCMD's
  10.         Can anyone help me with the Time Manager?
  11.         Dynamic Dialogs?
  12.         How to install your own templates using Macsbug 6.5d6???
  13.         IM: Networking book question
  14.         INIT Writing FAQ [1-3]
  15.         INIT Writing FAQ [2-3]
  16.         INIT Writing FAQ [3-3]
  17.         Linking 68k object files to PPC program
  18.         Network Programming
  19.         Stuck in SyncWait again
  20.         having trouble with AEInteractWithUser & drag manager
  21.  
  22.  
  23.  
  24. The Comp.Sys.Mac.Programmer Digest is moderated by Francois Pottier
  25. (pottier@clipper.ens.fr).
  26.  
  27. The digest is a collection of article threads from the internet newsgroup
  28. comp.sys.mac.programmer.  It is designed for people who read c.s.m.p. semi-
  29. regularly and want an archive of the discussions.  If you don't know what a
  30. newsgroup is, you probably don't have access to it.  Ask your systems
  31. administrator(s) for details.  If you don't have access to news, you may
  32. still be able to post messages to the group by using a mail server like
  33. anon.penet.fi (mail help@anon.penet.fi for more information).
  34.  
  35. Each issue of the digest contains one or more sets of articles (called
  36. threads), with each set corresponding to a 'discussion' of a particular
  37. subject.  The articles are not edited; all articles included in this digest
  38. are in their original posted form (as received by our news server at
  39. nef.ens.fr).  Article threads are not added to the digest until the last
  40. article added to the thread is at least two weeks old (this is to ensure that
  41. the thread is dead before adding it to the digest).  Article threads that
  42. consist of only one message are generally not included in the digest.
  43.  
  44. The digest is officially distributed by two means, by email and ftp.
  45.  
  46. If you want to receive the digest by mail, send email to listserv@ens.fr
  47. with no subject and one of the following commands as body:
  48.     help                        Sends you a summary of commands
  49.     subscribe csmp-digest Your Name    Adds you to the mailing list
  50.     signoff csmp-digest            Removes you from the list
  51. Once you have subscribed, you will automatically receive each new
  52. issue as it is created.
  53.  
  54. The official ftp info is //ftp.dartmouth.edu/pub/csmp-digest.
  55. Questions related to the ftp site should be directed to
  56. scott.silver@dartmouth.edu. Currently no previous volumes of the CSMP
  57. digest are available there.
  58.  
  59. Also, the digests are available to WAIS users.  To search back issues
  60. with WAIS, use comp.sys.mac.programmer.src. With Mosaic, use
  61. http://www.wais.com/wais-dbs/comp.sys.mac.programmer.html.
  62.  
  63.  
  64. -------------------------------------------------------
  65.  
  66. >From Tom_Brodhurst-Hill@intouch.mpx.com.au (Tom Brodhurst-Hill)
  67. Subject: (Q) AppleScript & XCMD's
  68. Date: 31 Oct 1994 19:07:41 GMT
  69. Organization: MacInTouch BBS
  70.  
  71. Can anyone tell me whether XCMD's (typically for HyperCard) can be included in
  72. and accessed by a compiled AppleScript application, without running a
  73. separate HyperCard process?
  74. Thanks,
  75. Tom
  76. please email to tombh@intouch.mpx.com.au
  77. and post too for others.
  78.                             MacInTouch BBS
  79. info@intouch.mpx.com.au     Ph. 61 2 541 1287    BBS. 61 2 541 0799
  80. *** Sent by FirstClass the graphical email system by SoftArc. Inc. ***
  81.  
  82. +++++++++++++++++++++++++++
  83.  
  84. >From lai@apple.com (Ed Lai)
  85. Date: Mon, 31 Oct 1994 17:20:39 GMT
  86. Organization: Apple
  87.  
  88. In article <29224926.900353@intouch.intouch.mpx.com.au>,
  89. Tom_Brodhurst-Hill@intouch.mpx.com.au (Tom Brodhurst-Hill) wrote:
  90.  
  91. > Can anyone tell me whether XCMD's (typically for HyperCard) can be included in
  92. > and accessed by a compiled AppleScript application, without running a
  93. > separate HyperCard process?
  94. > Thanks,
  95. > Tom
  96. > please email to tombh@intouch.mpx.com.au
  97. > and post too for others.
  98. >                             MacInTouch BBS
  99. > info@intouch.mpx.com.au     Ph. 61 2 541 1287    BBS. 61 2 541 0799
  100. > *** Sent by FirstClass the graphical email system by SoftArc. Inc. ***
  101.  
  102. It depends on the XCMD, a lot of them can be used, but if they are
  103. very dependent on HyperCard specifc callback or globals, then they
  104. cannot.
  105.  
  106. Try to download the XCMD OSAX.
  107.  
  108. Generally the place to look for AppleScript related stuff is in
  109. gaea.kgs.ukans.edu.
  110.  
  111. If it is just for the XCMD OSAX, you may try ftp.apple.com in
  112. /pub/lai/osax.
  113.  
  114. It is an adaptor for AppleScript to use XCMDs. It also comes installed
  115. with a number of XCMDs by Rinaldi as examples.
  116.  
  117. In theory you can try it with any other XCMD/XFCNs you got. However to
  118. do that requires writing certain resources and that is not a easy
  119. job if you are doing it the first time.
  120.  
  121. -- 
  122. /* Disclaimer: All statments and opinions expressed are my own */
  123. /* Edmund K. Lai                                               */
  124. /* Apple Computer, MS303-3A                                    */
  125. /* 20525 Mariani Ave,                                          */
  126. /* Cupertino, CA 95014                                         */
  127. /* (408)974-6272                                               */
  128. zW@h9cOi
  129.  
  130. ---------------------------
  131.  
  132. >From anthonym@puree.ugcs.caltech.edu (Anthony Molinaro)
  133. Subject: Can anyone help me with the Time Manager?
  134. Date: 21 Oct 1994 08:09:59 GMT
  135. Organization: California Institute of Technology, Pasadena
  136.  
  137.  
  138. I worked on this piece of code for a friend using Symatec 
  139. THINK C which turns on the power to a digital I/O board, 
  140. delays for a certain number of ticks, and then turns the 
  141. power off. This was my first time programming on a Macintosh 
  142. and so I had to search a little bit to find out about Delay.  
  143. Now, he tells me he needs a delay time smaller than one tick.  
  144. I know that the time manager can do this but I have been 
  145. unable to get it to work.  I guess my confusion arises in the
  146. type declarations and getting all of the types to match for 
  147. functions InsXTime(), PrimeTime(), and such.  The Inside 
  148. Macintosh doesn't have any examples in C and I have not been 
  149. able to accurately port the Pascal functions with the proper
  150. type settings.  My midterms are quickly approaching but I 
  151. promised I would help him out, so any help that anyone could
  152. give would be .
  153.  
  154.  
  155.  
  156. /* Here is the original code */
  157.  
  158. void Play(int note, unsigned long time)
  159. {  long finalTicks;
  160.    short error;
  161.  
  162.    /* turn on power for port,line: portout, lineout */
  163.    error = DIG_Out_Line(4, notes[note].portout, notes[note].line, 1);
  164.    chkerr("DIG_Out_Line",error);
  165.  
  166.    /* if power is on delay */
  167.    if(error == 0)
  168.      Delay(time,&finalTicks);
  169.  
  170.    /* turn off power */
  171.    error = DIG_Out_Line(4, notes[note].portout, notes[note].line, 0);
  172.    chkerr("DIG_Out_Line",error);
  173. }
  174.  
  175. /* Here is what I tryed */
  176. /* global variables     */
  177.  
  178. int note;
  179. TMTask tblah;
  180.  
  181. pascal void MyTimeTask(void)
  182. { DIG_Out_Line(4, notes[note].portout, notes[note].line, 0);
  183. }
  184.  
  185. void MyDelay(unsigned long time)
  186. { tblah.tmAddr = &MyTimeTask();
  187.   tblah.tmWakeUp = 0;
  188.   tblah.tmReserved = 0;
  189.   InsXTime(&tblah);
  190.   PrimeTime(&tblah,time);
  191. }
  192.  
  193. This didn't work, and I don't have a lot of time to figure out 
  194. why, so if anyone has any ideas I'm open to them.  Thanks in
  195. advance.  Reply through e-mail if possible.
  196.  
  197. =====================================================================
  198. Anthony Molinaro
  199. anthonym@ugcs.caltech.edu
  200.  
  201.  
  202.  
  203.  
  204. +++++++++++++++++++++++++++
  205.  
  206. >From Carl R. Osterwald <carl_osterwald@nrel.gov>
  207. Date: Fri, 21 Oct 1994 17:23:44 GMT
  208. Organization: National Renewable Energy Laboratory
  209.  
  210. In article <387t0n$3rr@gap.cco.caltech.edu> Anthony Molinaro,
  211. anthonym@puree.ugcs.caltech.edu writes:
  212. >Now, he tells me he needs a delay time smaller than one tick.  
  213. >I know that the time manager can do this but I have been 
  214. >unable to get it to work.  I guess my confusion arises in the
  215. >type declarations and getting all of the types to match for 
  216. >functions InsXTime(), PrimeTime(), and such.  The Inside 
  217.  
  218. Here is an example of a Time Manager task:
  219.  
  220. typedef struct
  221.     {
  222.         TMTask        tm_task;
  223.         long        A5;
  224.     } time_info;
  225.  
  226. Initialization:
  227.     timer_rec.tm_task.tmAddr = (TimerProcPtr)&time_task;
  228.     timer_rec.tm_task.tmWakeUp = 0;
  229.     timer_rec.tm_task.tmReserved = 0;
  230.     timer_rec.A5 = SetCurrentA5();
  231.     InsXTime( (QElemPtr)&timer_rec );
  232.     PrimeTime( (QElemPtr)timer_rec, period );  <<-- This starts the task
  233.  
  234. static void time_task (void)
  235.     {
  236.         time_info    *timer_rec;
  237.         long        current_A5;
  238.         
  239.         asm
  240.             {
  241.                 MOVE.L        A1,timer_rec
  242.                 MOVE.L        A5,current_A5
  243.             };
  244.         SetA5(timer_rec->A5);
  245.         PrimeTime( (QElemPtr)timer_rec, period );  <<-- This restarts the task
  246.         SetA5(current_A5);
  247.     }    // time_task
  248.  
  249. You can access your globals between the SetA5 calls.  Because the time
  250. task runs as an interrupt, it is best to minimize processing inside.  In
  251. your case, I would just set a global flag that is polled in the main
  252. event loop to see if it is time to turn the device on or off.
  253.  
  254. +++++++++++++++++++++++++++
  255.  
  256. >From h+@nada.kth.se (Jon W{tte)
  257. Date: Fri, 21 Oct 1994 18:48:34 +0100
  258. Organization: Royal Institute of Something or other
  259.  
  260. In article <387t0n$3rr@gap.cco.caltech.edu>,
  261. anthonym@puree.ugcs.caltech.edu (Anthony Molinaro) wrote:
  262.  
  263. >Now, he tells me he needs a delay time smaller than one tick.  
  264. >I know that the time manager can do this but I have been 
  265. >unable to get it to work.  I guess my confusion arises in the
  266.  
  267.  
  268. All you need is the system call Microseconds. You can write 
  269. your own Delay.
  270.  
  271. Cheers,
  272.  
  273.                 / h+
  274.  
  275.  
  276. --
  277.   Jon Wätte (h+@nada.kth.se), Hagagatan 1, 113 48 Stockholm, Sweden
  278.     Not speaking for the Microsoft Corporation.
  279.  
  280.  
  281. +++++++++++++++++++++++++++
  282.  
  283. >From gbolsinga@aol.com (GBolsinga)
  284. Date: 24 Oct 1994 17:20:05 -0400
  285. Organization: America Online, Inc. (1-800-827-6364)
  286.  
  287. In article <387t0n$3rr@gap.cco.caltech.edu>,
  288. anthonym@puree.ugcs.caltech.edu (Anthony Molinaro) writes:
  289.  
  290. >pascal void MyTimeTask(void)
  291. >{ DIG_Out_Line(4, notes[note].portout, notes[note].line, 0);
  292. >}
  293.  
  294. Look at the other sample code: it looks good.  Another problem might
  295. be that this function DIG_Out_Line can't move memory.
  296.  
  297. MyTimeTask executes at interupt time, so just set a global, and in
  298. your idle in your event loop check for the global changing and then
  299. call your function.
  300.  
  301. Greg Bolsinga
  302. MPI Multimedia
  303.  
  304.  
  305. +++++++++++++++++++++++++++
  306.  
  307. >From Tim Dorcey <td11@cornell.edu>
  308. Date: 25 Oct 1994 19:01:49 GMT
  309. Organization: Cornell University
  310.  
  311. In article <AACDBD82966813F759@klkmac005.nada.kth.se> Jon W{tte,
  312. h+@nada.kth.se writes:
  313. >All you need is the system call Microseconds. You can write 
  314. >your own Delay.
  315.  
  316. Do anyone know where the Microseconds call is documented?  I stumbled
  317. upon it in <Timer.h>, but can't find documentation for it anywhere.  Is
  318. it safe to assume that it is available on any system that has the
  319. "Revised Time Manager?"  I had written my own version, using
  320. InsTime/RmvTime, which seems to work fine, but I'd just as soon use the
  321. system call if it's equally available.
  322.  
  323. Tim Dorcey
  324. Tim_Dorcey@cornell.edu
  325.  
  326. ---------------------------
  327.  
  328. >From joey@caseware.com (Joey Caturay)
  329. Subject: Dynamic Dialogs?
  330. Date: Thu, 13 Oct 1994 15:15:23 GMT
  331. Organization: CaseWare
  332.  
  333. I seem to recall a MacTutor/Tech article about writing dynamic dialogs (i.e. 
  334. dialogs in which controls change based on a selection in the dialog. The 
  335. Metrowerks Project Preference dialog is an example). 
  336.  
  337. Is there source anywhere for dynamic dialogs? 
  338.  
  339. Thanks,
  340.  
  341. joey 
  342.  
  343. +++++++++++++++++++++++++++
  344.  
  345. >From johns@efn.org (John Selhorst)
  346. Date: Fri, 14 Oct 1994 01:07:40 GMT
  347. Organization: hisself
  348.  
  349. In article <joey.23.2E9D4F0B@caseware.com>, joey@caseware.com (Joey
  350. Caturay) wrote:
  351.  
  352. > I seem to recall a MacTutor/Tech article about writing dynamic dialogs (i.e. 
  353. > dialogs in which controls change based on a selection in the dialog. The 
  354. > Metrowerks Project Preference dialog is an example). 
  355. > Is there source anywhere for dynamic dialogs? 
  356. > Thanks,
  357. > joey 
  358.  
  359. There are some nice snippets with dynamic dialogs on the developer CD and
  360. probably on ftp.apple.com or whatever it's called now.
  361.  
  362. Johnny
  363.  
  364. johns@efn.org
  365.  
  366. +++++++++++++++++++++++++++
  367.  
  368. >From gurgle@dnai.com (Pete Gontier)
  369. Date: Sat, 15 Oct 1994 02:39:20 -0800
  370. Organization: Integer Poet Software
  371.  
  372. In article <joey.23.2E9D4F0B@caseware.com>, joey@caseware.com (Joey
  373. Caturay) wrote:
  374.  
  375. > I seem to recall a MacTutor/Tech article about writing dynamic dialogs (i.e. 
  376. > dialogs in which controls change based on a selection in the dialog. The 
  377. > Metrowerks Project Preference dialog is an example). 
  378. > Is there source anywhere for dynamic dialogs? 
  379.  
  380. Just get creative with HideDItem and ShowDItem. I recently implemented a
  381. NewsWatcher-style dialog this way (and it was no coincidence...). There's
  382. a popup menu at the top from which the user can select a set of dialog
  383. items. The items always exist, but most of them are hidden most of the
  384. time. Creating this dialog can be a pain unless you have a cool dialog
  385. editor like the one in Resorcerer which actually lets you show and hide
  386. ranges of items in the same way the Dialog Manager will do at run-time.
  387. (It's been 
  388.  
  389. This all said, if you're contemplating doing this, it may also be the case
  390. that you are running into other limitations of the Dialog Manager.
  391. Consider using something else, like any one of the several commercial
  392. view-management systems (off the top of my head, QuickApp, AppsToGo,
  393. MacApp, TCL, PowerPlant, FaceIt), or roll your own. (It's not all that
  394. hard if all you want is a list of items like the Dialog Manager tracks.
  395. Trees get messy, of course.)
  396.  
  397. -- 
  398.  
  399.  Pete Gontier // CTO, Integer Poet Software // gurgle@dnai.com
  400.  
  401.  "A Princeton Review executive said the whole affair was not that important
  402.   and offered to relinquish the Kaplan domain name 'for a case of beer'."
  403.         -- Chris Gulker, SF Examiner
  404.  
  405. +++++++++++++++++++++++++++
  406.  
  407. >From gurgle@dnai.com
  408. Date: 14 Oct 94 21:39 GMT+0300
  409. Organization: (none)
  410.  
  411. In article <joey.23.2E9D4F0B@caseware.com>, joey@caseware.com (Joey
  412. Caturay) wrote:
  413.  
  414. > I seem to recall a MacTutor/Tech article about writing dynamic dialogs (i.e. 
  415. > dialogs in which controls change based on a selection in the dialog. The 
  416. > Metrowerks Project Preference dialog is an example). 
  417. > Is there source anywhere for dynamic dialogs? 
  418.  
  419. Just get creative with HideDItem and ShowDItem. I recently implemented a
  420. NewsWatcher-style dialog this way (and it was no coincidence...). There's
  421. a popup menu at the top from which the user can select a set of dialog
  422. items. The items always exist, but most of them are hidden most of the
  423. time. Creating this dialog can be a pain unless you have a cool dialog
  424. editor like the one in Resorcerer which actually lets you show and hide
  425. ranges of items in the same way the Dialog Manager will do at run-time.
  426. (It's been 
  427.  
  428. This all said, if you're contemplating doing this, it may also be the case
  429. that you are running into other limitations of the Dialog Manager.
  430. Consider using something else, like any one of the several commercial
  431. view-management systems (off the top of my head, QuickApp, AppsToGo,
  432. MacApp, TCL, PowerPlant, FaceIt), or roll your own. (It's not all that
  433. hard if all you want is a list of items like the Dialog Manager tracks.
  434. Trees get messy, of course.)
  435.  
  436. -- 
  437.  
  438.  Pete Gontier // CTO, Integer Poet Software // gurgle@dnai.com
  439.  
  440.  "A Princeton Review executive said the whole affair was not that important
  441.   and offered to relinquish the Kaplan domain name 'for a case of beer'."
  442.         -- Chris Gulker, SF Examiner
  443.  
  444. +++++++++++++++++++++++++++
  445.  
  446. >From ivan_cavero_belaunde@avid.com (Ivan Cavero Belaunde)
  447. Date: 18 Oct 1994 15:49:43 GMT
  448. Organization: Avid Technology, Inc.
  449.  
  450. In article <gurgle-1510940239200001@dynamic-215.dnai.com>, gurgle@dnai.com
  451. (Pete Gontier) wrote:
  452.  
  453. > In article <joey.23.2E9D4F0B@caseware.com>, joey@caseware.com (Joey
  454. > Caturay) wrote:
  455. > > I seem to recall a MacTutor/Tech article about writing dynamic dialogs
  456. (i.e. 
  457. > > dialogs in which controls change based on a selection in the dialog. The 
  458. > > Metrowerks Project Preference dialog is an example). 
  459. > > Is there source anywhere for dynamic dialogs? 
  460. > Just get creative with HideDItem and ShowDItem. I recently implemented a
  461. > NewsWatcher-style dialog this way (and it was no coincidence...). There's
  462. > a popup menu at the top from which the user can select a set of dialog
  463. > items. The items always exist, but most of them are hidden most of the
  464. > time. Creating this dialog can be a pain unless you have a cool dialog
  465. > editor like the one in Resorcerer which actually lets you show and hide
  466. > ranges of items in the same way the Dialog Manager will do at run-time.
  467. > (It's been 
  468.  
  469. I thought NewsWatcher used AppendDITL, RemoveDITL, etc. I do remember
  470. John's sample code from disinfectant containing routines along the lines
  471. of AppendDITL and RemoveDITL to allow you to append and remove items to
  472. the dialog (the Sys7/CTB routines of the same names work as long as you
  473. DON'T use 'ictb' resources - otherwise they can crash horribly). I don't
  474. have any source, but you might also want to look at either the QuickTime
  475. Sequence Grabber Panel Component API or the Sound Control Panel Component
  476. API for some pointers and ideas - it defines a clean layer between a main
  477. piece of code that you write that controls the main dialog (ie the NW
  478. popup menu or the "scrolling icon item" list in CW) and "plug-in"
  479. subcomponents that control the independent panels.
  480.  
  481. -Ivan
  482. - --
  483. Ivan Cavero Belaunde (ivan_cavero_belaunde@avid.com)
  484. Avid VideoShop Lead
  485. Avid Technology, Inc.
  486. Disclaimer:  All views expressed are entirely my own and do not
  487. reflect  the opinions of Avid Technology, Inc.
  488.  
  489. +++++++++++++++++++++++++++
  490.  
  491. >From reed@medicine.wustl.edu (Thomas Reed)
  492. Date: Tue, 18 Oct 1994 11:21:13 -0500
  493. Organization: Washington University
  494.  
  495. In article <gurgle-1510940239200001@dynamic-215.dnai.com>, gurgle@dnai.com
  496. (Pete Gontier) wrote:
  497.  
  498. >In article <joey.23.2E9D4F0B@caseware.com>, joey@caseware.com (Joey
  499. >Caturay) wrote:
  500. >
  501. >> I seem to recall a MacTutor/Tech article about writing dynamic dialogs
  502. >
  503. >Just get creative with HideDItem and ShowDItem.
  504.  
  505. The method I like better is to set up your dialog with a "base" DITL,
  506. containing whatever controls are going to be static for all settings. 
  507. This might contain your OK and Cancel buttons and a pop-up, if that's the
  508. method you want to use to switch to a different set of controls.  Then,
  509. you define a separate DITL for each setting (say you have an options
  510. dialog with three different options topics selectable on a pop-up menu,
  511. you use 3 different DITLs, one for each topic).  Make sure that the new
  512. DITL can be overlayed on the "base" DITL the way you want it.  I believe
  513. that you may also want to specify that the "base" DLOG is not initially
  514. visible.
  515.  
  516. Then, in your program, you use AppendDITL to overlay the DITLs.  Just open
  517. your base DLOG, then call AppendDITL to overlay the current setting on the
  518. base DITL.  The item numbers for the one you're adding will be bumped up
  519. by the number of items in your base DITL.
  520.  
  521. Then, when the user switches to a different set of controls, you use
  522. ShortenDITL to remove the old controls and AppendDITL to add the new set.
  523.  
  524. You've of course also got to take into account which set of controls
  525. you're using in your dialog handling routines, as item #5 under one
  526. setting may not be the same as item #5 under another.  However, this is
  527. not too hard to do.
  528.  
  529. I believe that this is the way that NewsWatcher does things.
  530.  
  531. -Thomas
  532.  
  533. =====================================================
  534. Thomas Reed                     Washington University
  535. reed@telesphere.wustl.edu           Medical School
  536. reed@medicine.wustl.edu            Saint Louis, MO
  537. - ---------------------------------------------------
  538. Clothes make the man.  Naked people have little or no
  539. influence on society.  -- Mark Twain
  540. =====================================================
  541.  
  542. Opinions posted are not the opinions of Wash. U.
  543.  
  544. +++++++++++++++++++++++++++
  545.  
  546. >From bb@lightside.com (Bob Bradley)
  547. Date: Mon, 17 Oct 1994 03:22:02 -0800
  548. Organization: SS Software Inc.
  549.  
  550. In article <ivan_cavero_belaunde-1810941144230001@predator.avid.com>,
  551. ivan_cavero_belaunde@avid.com (Ivan Cavero Belaunde) wrote:
  552.  
  553. > I thought NewsWatcher used AppendDITL, RemoveDITL, etc. I do remember
  554. > John's sample code from disinfectant containing routines along the lines
  555. > of AppendDITL and RemoveDITL to allow you to append and remove items to
  556. > the dialog (the Sys7/CTB routines of the same names work as long as you
  557. > DON'T use 'ictb' resources - otherwise they can crash horribly).
  558.  
  559. Any dialog with an ictb resource can't use AppendDITL/ShortenDITL? Is
  560. there any other way to get the functionality of those two routines when
  561. using dialogs with ictb resources without modifying the DITL in memory
  562. directly?
  563.  
  564. I had a lot problems in the past with AppendDITL and ShortenDITL and could
  565. never figure it out until you mentioned they didn't work with ictb
  566. resources. I end up using the Show/Hide method but, when working with
  567. dialogs with a lot of items, it gets difficult.
  568.  
  569. +++++++++++++++++++++++++++
  570.  
  571. >From rmah@panix.com (Robert Mah)
  572. Date: Tue, 18 Oct 1994 18:15:26 -0500
  573. Organization: One Step Beyond
  574.  
  575. Jason_Titus@odsnet.com wrote:
  576.  
  577.  ) I have been trying to work out a solution to a problem where I have a
  578.  ) base window and can have a thousand or so possible midifications.  It
  579.  ) sounds like having these numerous DITL's and appending them would be
  580.  ) the best solutions,but - 
  581.  ) 
  582.  ) how do I create DITLs?  I can't find real descriptions of their format..
  583.  ) My goal is to be able to create DITLs from text files of information
  584.  ) (ie - a text file made up of checkbox titles) so I can easily create
  585.  ) thousands of windows.
  586.  
  587. The usual way is to use ResEdit's or Resorcerer's graphical editors.
  588.  
  589. However given that you want to parse a text file to create user interfaces,
  590. and assuming that the text file is not in rez format, I think you're going
  591. to have to write a parser and create windows on the fly.  That is, don't
  592. use DITL and DLOG resources, but instead operate directly at the Window
  593. Manager, Control Manager, List Manager and TextEdit levels.
  594.  
  595. Depending upon the complexity of your "interface description language",
  596. this might not be too hard or it might be a royal pain in the...
  597.  
  598. Cheers,
  599. Rob
  600. _____________________________________________________________________
  601. Robert S. Mah           Software Development          +1.212.947.6507
  602. One Step Beyond        and Network Consulting          rmah@panix.com
  603.  
  604. +++++++++++++++++++++++++++
  605.  
  606. >From leonardr@netcom.com (Leonard Rosenthol)
  607. Date: Wed, 19 Oct 1994 21:47:29 GMT
  608. Organization: Aladdin Systems, Inc.
  609.  
  610. In article <bb-1710940322020001@user31.lightside.com>, bb@lightside.com
  611. (Bob Bradley) wrote:
  612.  
  613. > In article <ivan_cavero_belaunde-1810941144230001@predator.avid.com>,
  614. > ivan_cavero_belaunde@avid.com (Ivan Cavero Belaunde) wrote:
  615. > > I thought NewsWatcher used AppendDITL, RemoveDITL, etc. I do remember
  616. > > John's sample code from disinfectant containing routines along the lines
  617. > > of AppendDITL and RemoveDITL to allow you to append and remove items to
  618. > > the dialog (the Sys7/CTB routines of the same names work as long as you
  619. > > DON'T use 'ictb' resources - otherwise they can crash horribly).
  620. > Any dialog with an ictb resource can't use AppendDITL/ShortenDITL? Is
  621. > there any other way to get the functionality of those two routines when
  622. > using dialogs with ictb resources without modifying the DITL in memory
  623. > directly?
  624.    That info about 'ictb's is NOT true.  The System routines AppendDITL
  625. and ShortenDITL will work just fine with ictb's GIVEN THE LIMITATIONS of
  626. ictb resources (like they suck big time!).
  627.  
  628.  
  629. Leonard
  630. - ------------------------------------------------------------------------
  631. Leonard Rosenthol                      Internet:       leonardr@netcom.com
  632. Director of Advanced Technology        AppleLink:      MACgician
  633. Aladdin Systems, Inc.                  GEnie:          MACgician
  634.  
  635. +++++++++++++++++++++++++++
  636.  
  637. >From ivan_cavero_belaunde@avid.com (Ivan Cavero Belaunde)
  638. Date: 21 Oct 1994 14:44:58 GMT
  639. Organization: Avid Technology, Inc.
  640.  
  641. In article <bb-1710940322020001@user31.lightside.com>, bb@lightside.com
  642. (Bob Bradley) wrote:
  643. > In article <ivan_cavero_belaunde-1810941144230001@predator.avid.com>,
  644. > ivan_cavero_belaunde@avid.com (Ivan Cavero Belaunde) wrote:
  645. > > I thought NewsWatcher used AppendDITL, RemoveDITL, etc. I do remember
  646. > > John's sample code from disinfectant containing routines along the lines
  647. > > of AppendDITL and RemoveDITL to allow you to append and remove items to
  648. > > the dialog (the Sys7/CTB routines of the same names work as long as you
  649. > > DON'T use 'ictb' resources - otherwise they can crash horribly).
  650. > Any dialog with an ictb resource can't use AppendDITL/ShortenDITL? Is
  651. > there any other way to get the functionality of those two routines when
  652. > using dialogs with ictb resources without modifying the DITL in memory
  653. > directly?
  654. > I had a lot problems in the past with AppendDITL and ShortenDITL and could
  655. > never figure it out until you mentioned they didn't work with ictb
  656. > resources. I end up using the Show/Hide method but, when working with
  657. > dialogs with a lot of items, it gets difficult.
  658.  
  659. Yeah, I had a lot of problems with those as well. Some of the problems
  660. (text items changing colors, for example) hinted at a confused 'ictb', so
  661. I stopped using one and everything was fine (it meant I had to use
  662. useritems for some stuff, though). This suspicion was confirmed by someone
  663. on the net who had worked on the AppendDITL/ShortenDITL code for Apple -
  664. 'ictb's are not supported by those calls.
  665.  
  666. Upon rereading my post above, I realize I imply John Norstad's
  667. DITL-manipulation code supports 'ictb'. I actually don't know whether
  668. that's the case or not - but it'd be easy to check if you need that
  669. functionality.
  670.  
  671. -Ivan
  672. - --
  673. Ivan Cavero Belaunde (ivan_cavero_belaunde@avid.com)
  674. Avid VideoShop Lead
  675. Avid Technology, Inc.
  676. Disclaimer:  All views expressed are entirely my own and do not
  677. reflect  the opinions of Avid Technology, Inc.
  678.  
  679. +++++++++++++++++++++++++++
  680.  
  681. >From Peter_Gontier@novell.com (Pete Gontier)
  682. Date: Mon, 24 Oct 1994 20:05:03 -0800
  683. Organization: Novell, Inc., Walnut Creek Macintosh Site
  684.  
  685. In article <ivan_cavero_belaunde-1810941144230001@predator.avid.com>,
  686. ivan_cavero_belaunde@avid.com (Ivan Cavero Belaunde) wrote:
  687.  
  688. > In article <gurgle-1510940239200001@dynamic-215.dnai.com>, gurgle@dnai.com
  689. > (Pete Gontier) wrote:
  690. > > Just get creative with HideDItem and ShowDItem. I recently implemented a
  691. > > NewsWatcher-style dialog this way...
  692. > I thought NewsWatcher used AppendDITL, RemoveDITL, etc...
  693.  
  694. I don't know for sure what NewsWatcher uses, but what I remember of the
  695. way he stored his DITLs supports the notion that he's using AppendDITL,
  696. etc.
  697.  
  698. When I said "NewsWatcher-style" I only meant the user interface is similar.
  699.  
  700. -- 
  701.  Views expressed here do not necessarily reflect the views of Novell.
  702.  
  703. +++++++++++++++++++++++++++
  704.  
  705. >From ivan_cavero_belaunde@avid.com (Ivan Cavero Belaunde)
  706. Date: 31 Oct 1994 19:43:51 GMT
  707. Organization: Avid Technology, Inc.
  708.  
  709. In article <leonardr-1910941347290001@leonardr.slip.netcom.com>,
  710. leonardr@netcom.com (Leonard Rosenthol) wrote:
  711.  
  712. > In article <bb-1710940322020001@user31.lightside.com>, bb@lightside.com
  713. > (Bob Bradley) wrote:
  714. > > In article <ivan_cavero_belaunde-1810941144230001@predator.avid.com>,
  715. > > ivan_cavero_belaunde@avid.com (Ivan Cavero Belaunde) wrote:
  716. > > 
  717. > > > I thought NewsWatcher used AppendDITL, RemoveDITL, etc. I do remember
  718. > > > John's sample code from disinfectant containing routines along the lines
  719. > > > of AppendDITL and RemoveDITL to allow you to append and remove items to
  720. > > > the dialog (the Sys7/CTB routines of the same names work as long as you
  721. > > > DON'T use 'ictb' resources - otherwise they can crash horribly).
  722. > > 
  723. > > Any dialog with an ictb resource can't use AppendDITL/ShortenDITL? Is
  724. > > there any other way to get the functionality of those two routines when
  725. > > using dialogs with ictb resources without modifying the DITL in memory
  726. > > directly?
  727. >    That info about 'ictb's is NOT true.  The System routines AppendDITL
  728. > and ShortenDITL will work just fine with ictb's GIVEN THE LIMITATIONS of
  729. > ictb resources (like they suck big time!).
  730.  
  731. Are you sure? I had an exchange on the net about a year/year and a half
  732. ago with someone (his name slips me) that had worked on the
  733. Append/RemoveDITL routines at Apple, and he explicitly mentioned that they
  734. didn't support 'ictb's. This was at the time when I was having problems
  735. with them: I kept getting items coming up in funny colors and fonts when I
  736. appended them, as well as stray crashes inside UpdateDialog. Nuking the
  737. 'ictb's got rid of all those problems.
  738.  
  739. On a related note, how do they suck big time? My only beef is that they
  740. are hard to edit unless you have Resorcerer, which is another one of the
  741. bazillion reasons to get Resorcerer and skip ResEdit...
  742.  
  743. -Ivan
  744. - --
  745. Ivan Cavero Belaunde (ivan_cavero_belaunde@avid.com)
  746. Avid VideoShop Lead
  747. Avid Technology, Inc.
  748. Disclaimer:  All views expressed are entirely my own and do not
  749. reflect  the opinions of Avid Technology, Inc.
  750.  
  751. ---------------------------
  752.  
  753. >From hsieh@netcom.com (Julia Hsieh)
  754. Subject: How to install your own templates using Macsbug 6.5d6???
  755. Date: Mon, 31 Oct 1994 17:25:57 GMT
  756. Organization: NETCOM On-line Communication Services (408 261-4700 guest)
  757.  
  758.  
  759. i've just started playing with custom templates in Macsbug, but since
  760. the new version doesn't have a separate Debugger Prefs file with the
  761. resources in it, how do i add my own custom templates?
  762.  
  763. also, i'm confused from one of the recent threads, is the Debugger
  764. Prefs a file or a folder.
  765.  
  766. thanks.
  767. -julia
  768.  
  769. -- 
  770. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  771. If each day falls
  772. inside each night,
  773. there exists a well
  774. where clarity is imprisoned.
  775.  
  776. We need to sit on the rim
  777. of the well of darkness
  778. and fish for fallen light
  779. with patience.
  780.  
  781.     -Pablo Neruda
  782. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  783.  
  784. +++++++++++++++++++++++++++
  785.  
  786. >From johns@efn.org (John Selhorst)
  787. Date: Tue, 1 Nov 1994 14:29:33 GMT
  788. Organization: hisself
  789.  
  790. In article <hsiehCyJsFA.7vH@netcom.com>, hsieh@netcom.com (Julia Hsieh) wrote:
  791.  
  792. > i've just started playing with custom templates in Macsbug, but since
  793. > the new version doesn't have a separate Debugger Prefs file with the
  794. > resources in it, how do i add my own custom templates?
  795. > also, i'm confused from one of the recent threads, is the Debugger
  796. > Prefs a file or a folder.
  797. > thanks.
  798. > -julia
  799.  
  800. You've almost answered your own question.  Yes, Debugger Prefs is a file
  801. that goes into the system folder.  It still works with MacsBug 6.5.  If
  802. you don't have one, make one yourself.  You can make one with ResEdit.
  803.  
  804. Johnny
  805.  
  806. johns@efn.org
  807.  
  808. +++++++++++++++++++++++++++
  809.  
  810. >From jonasw@lysator.liu.se (Jonas Wallden)
  811. Date: 1 Nov 1994 16:50:44 GMT
  812. Organization: (none)
  813.  
  814. hsieh@netcom.com (Julia Hsieh) writes:
  815.  
  816. >i've just started playing with custom templates in Macsbug, but since
  817. >the new version doesn't have a separate Debugger Prefs file with the
  818. >resources in it, how do i add my own custom templates?
  819.  
  820. I'm running 6.5d6 and it uses a Debugger Prefs file.
  821.  
  822. You can also drop your templates and macros into the MacsBug file itself.
  823. Just open it in ResEdit and paste them.
  824.  
  825. >also, i'm confused from one of the recent threads, is the Debugger
  826. >Prefs a file or a folder.
  827.  
  828. It's a resource file, and should be located at the top level of your
  829. System Folder.
  830.  
  831. >thanks.
  832. >-julia
  833.  
  834. BTW, welcome on board! You just doubled the female/male ratio of Mac hackers
  835. posting in this newsgroup... :-)
  836. ...............   .......................   ...........   ...............
  837.  jonas wallden           internet            applelink       phone/fax
  838.    mac hacker      jonasw@lysator.liu.se      sw1369       +46-13-176084
  839.  
  840. +++++++++++++++++++++++++++
  841.  
  842. >From devon_hubbard@taligent.com (Devon Hubbard)
  843. Date: Mon, 31 Oct 1994 18:57:56 GMT
  844. Organization: Taligent, Inc.
  845.  
  846. In article <hsiehCyJsFA.7vH@netcom.com>, hsieh@netcom.com (Julia Hsieh) wrote:
  847.  
  848. >i've just started playing with custom templates in Macsbug, but since
  849. >the new version doesn't have a separate Debugger Prefs file with the
  850. >resources in it, how do i add my own custom templates?
  851.  
  852. Since most of the dcmds/templates in the old 'Debugger Prefs' were always
  853. shipped with Macsbug, someone got smart at Apple (you know who you are :-)
  854. and just put that stuff in Macsbug itself and then there was no need for
  855. the separate prefs file.  This didn't eliminate the usage of that prefs
  856. file though.  So if you want to add your own templates, macros, etc. go
  857. right ahead and create a file called 'Debugger Prefs' and put your stuff
  858. in there.  The file type/creator is usually 'rsrc'/'RSED' but it really
  859. doesn't matter to Macsbug as it'll open the rsrc fork of any type file
  860. called 'Debugger Prefs'.
  861.  
  862. Also note that because Apple ships Macsbug this way, there is no need to
  863. merge their prefs with yours when a new release comes out.
  864.  
  865. dEVoN
  866.  
  867. - -----------------------------------------------------------------------
  868. Devon Hubbard                                               Silicon Pilot
  869. devon_hubbard@taligent.com                                  Taligent, Inc
  870. - -----------------------------------------------------------------------
  871. "No amount of genius can overcome a preoccupation with detail." -Einstein
  872.  
  873. ---------------------------
  874.  
  875. >From schultz@iastate.edu (Jonathan Schultz)
  876. Subject: IM: Networking book question
  877. Date: 28 Oct 94 07:08:51 GMT
  878. Organization: Iowa State University, Ames, Iowa
  879.  
  880. Does IM: Networking totally supercede Inside AppleTalk?
  881.  
  882. Jonathan
  883. schultz@iastate.edu
  884.  
  885. -- 
  886. - -----------------
  887. Jonathan Schultz
  888. schultz@iastate.edu
  889.  
  890. +++++++++++++++++++++++++++
  891.  
  892. >From jumplong@aol.com (Jump Long)
  893. Date: 29 Oct 1994 21:32:03 -0400
  894. Organization: America Online, Inc. (1-800-827-6364)
  895.  
  896. In article <schultz.783328131@pv3449.vincent.iastate.edu>,
  897. schultz@iastate.edu (Jonathan Schultz) writes:
  898.  
  899. >Does IM: Networking totally supercede Inside AppleTalk?
  900.  
  901. No it doesn't.
  902.  
  903. IM: Networking replaces the AppleTalk chapters of Inside Macintosh volumes
  904. II, IV, V, and VI (the old Inside Macintosh volumes).  IM: Networking
  905. describes the Macintosh AppleTalk API.  Inside AppleTalk describes the
  906. AppleTalk *protocols* - not the API for any particular implementation of
  907. AppleTalk.
  908.  
  909. While Inside AppleTalk isn't required to use most parts of the Macintosh
  910. AppleTalk API, it is useful when debugging AppleTalk problems you may have
  911. when using the Macintosh API because it describes the network packets and
  912. describes how the protocol was designed to be used.  To use some parts of
  913. the Macintosh API, you must have Inside AppleTalk because the Macintosh
  914. API doesn't build the request packets or disassemble the reply packets for
  915. you.  An example of that is using the .XPP driver to send AFP requests. 
  916. Since the system doesn't build those packets for you, you'll have to use
  917. the information in Inside AppleTalk to know how to build them yourself.
  918.  
  919. - Jim Luther
  920.  
  921. ---------------------------
  922.  
  923. >From Jaeger@fquest.com (Brian Stern)
  924. Subject: INIT Writing FAQ [1-3]
  925. Date: 28 Oct 1994 00:37:24 GMT
  926. Organization: The University of Texas at Austin, Austin, Texas
  927.  
  928. Answers to Frequently Asked Questions about writing System Extensions 
  929. on the Macintosh Computer. Version 1.0 10/94
  930.  
  931. This document is Copyright © 1994 by Brian Stern.
  932. I can be contacted by email at <Jaeger@fquest.com> on Internet.
  933.  
  934. The purpose of this FAQ list is to provide information on the writing 
  935. of system extensions.  This arcane art is difficult to learn and the 
  936. existing information on the subject is spread around in various 
  937. places.  Hopefully the information here will help new and old INIT 
  938. writers to write better INITs in less time.
  939.  
  940. The questions in this document are broken into two sections: System 
  941. Extensions and Trap Patches.  While most extensions contain trap 
  942. patches these subjects seemed different so I have separated them.
  943.  
  944. FAQ lists like this one are an integral part of Usenet.  When I 
  945. started reading Usenet news I assure you that I knew nothing about 
  946. writing extensions.  I learned by posting questions to 
  947. comp.sys.mac.programmer and by reading other's questions and 
  948. responses.  Let me take this space to give you a few tips on phrasing 
  949. of questions to newsgroups.
  950.  
  951. When asking a question try to make the title as descriptive as 
  952. possible.  Most people don't have time to read every question posted 
  953. and will ignore posts whose titles are unclear or meaningless.  Don't 
  954. post questions titled 'HELP, My program doesn't work', or worse 
  955. 'URGENT NEED HELP with program'.  I'm sure it's urgent to you, but 
  956. not to me.  Always indicate that you're asking a questing by 
  957. including a (you guessed it) question mark.  Consider these titles: 
  958. 'Programmers make big salaries' and 'Programmers make big salaries?'  
  959. Don't waste people's time with the former when you mean the latter.  
  960. Another way to indicate a question is like this: '[Q] Programmers 
  961. make big salaries?'.  Try to include one of the words 'who, what, 
  962. when, where, why, or how' in the titles of your questions.  Your 
  963. questions are much more likely to be answered by someone who actually 
  964. knows the answer if your title is clear.
  965.  
  966. The code samples in this document were developed with Think C.  You 
  967. may need to make some changes to use them with other development 
  968. systems.  I've used inline assembly in many of the code samples.  To 
  969. my eye this makes things more clear since it's obvious what's going 
  970. on.  Not everyone agrees with this and not all development 
  971. environments provide inline assembly.  It's possible to rewrite most 
  972. or all of this code by use of inline functions.  If you're writing in 
  973. Pascal or using CodeWarrior you'll have to do it that way.
  974.  
  975. You'll be able to find information on general questions of Mac 
  976. programming in the FAQ list maintained by Jon Watte at: 
  977. ftp://nada.kth.se/pub/hacks/mac-faq/CSMP_PD_FAQ
  978.  
  979. If you have questions about writing extensions that aren't addressed 
  980. in this document or any comments about it feel free to send them to 
  981. me.  If I know the answer or can find it out it may find its way into 
  982. a later version.
  983.  
  984. This document may be distributed freely as long as no changes are 
  985. made to it.  It may not be distributed in ways in which the user must 
  986. pay for the document, other than reasonable download costs or costs 
  987. for the medium, without the consent of the author.
  988.  
  989. Thanks to the following people who provided sample code and made 
  990. constructive comments: Pete Gontier, Dair Grant, Chelly Green, Devon 
  991. Hubbard, Peter Lewis, Jim Walker, Jim Wintermyre.
  992.  
  993. - -------------------------------------------------------------------
  994. System Extension Writing FAQ Outline:
  995.  
  996. System Extensions:
  997.  
  998. [1] What is an INIT, exactly?
  999. [2] Should I write an INIT?
  1000. [3] Can I write an INIT that makes the application menu into a 
  1001. hierarchical menu?
  1002. [4] Do I need to know assembler to write an INIT?
  1003. [5] Can you show me a sample INIT?
  1004. [6] Can I have global variables in my INIT?
  1005. [7] How do I debug an INIT?
  1006. [8] How do I write a Control Panel-INIT combination?
  1007. [9] How do I capture keystrokes?
  1008. [10] How can my extension get time periodically?
  1009. [11] How should an INIT manage memory?
  1010. [12] How do I get my INIT to turn itself off?
  1011. [13] How do I get my INIT to show its icon like all the other cool 
  1012. INITs do?
  1013. [14] How do I show a dialog from my INIT?
  1014. [15] How do I maintain compatibility with future systems?
  1015. [16] Any tips for INIT writing?
  1016.  
  1017. Trap Patches:
  1018.  
  1019. [17] What exactly is a trap patch?
  1020. [18] What's the difference between a head patch and a tail patch?
  1021. [19] How do I patch a trap?
  1022. [20] How do I patch a register-based trap?
  1023. [21] Can you show me an example tail patch?
  1024. [22] How do I patch a selector-based trap?
  1025. [23] How do I patch a trap on the PPC?
  1026. [24] Can I write a fat trap?
  1027. [25] Tips?
  1028. [26] What other sources of information are available?
  1029.  
  1030. - -------------------------------------------------------------------
  1031.  
  1032. [1] What is an INIT, exactly?
  1033.  
  1034. An INIT is a type of code resource that is loaded into memory and 
  1035. executed during the startup process.  They're called INITs because 
  1036. they're resources of type 'INIT'.  INITs load at the end of the 
  1037. startup process, after the hardware checks have been done and the 
  1038. system has been started.  The span of time during which INITs load 
  1039. and execute is known as INIT time.  Applications don't load until 
  1040. after INIT time and in most cases the first application to load is 
  1041. the Finder.
  1042.  
  1043. Because they load before all applications, INITs can modify the 
  1044. system in a way that affects all applications.  They can add new 
  1045. functionalities and modify the way in which many processes occur on 
  1046. the Mac.  Apple often supplies new additions and updates to system 
  1047. software as INITs.  This includes things such as the Drag-and-Drop 
  1048. Manager, Thread Manager, Speech Manager, and Sound Manager 3.0.  At 
  1049. some point these new features are rolled into a new software release 
  1050. and eventually they are included in new ROMs, but they all start life 
  1051. as INITs.
  1052.  
  1053. Apple recommends that the term 'system extension' be used when 
  1054. communicating with non-programmers.  This name carries the 
  1055. implication that they extend the functionality of the system.  You'll 
  1056. see the terms 'INIT', 'extension', and 'system extension' used to 
  1057. mean the same thing throughout this document.
  1058.  
  1059. Extensions are loaded in a defined order.  Resources of type 'INIT' 
  1060. can be found in files of type 'INIT' (System Extension), 'cdev' 
  1061. (Control Panel), 'RDEV' (Chooser Device), 'appe' (application 
  1062. extension), and 'scri' (script system extensions).  In order to be 
  1063. loaded, the INIT resource must be in one of these file types in one 
  1064. of several locations in the System Folder.  
  1065.  
  1066. Under system 7 INITs are loaded first from the Extensions Folder in 
  1067. alphabetical order.  INITs present in script system extension files 
  1068. (filetype 'scri') load before INITs present in system extension files 
  1069. (filetype 'INIT').  Next, any INITs in the Control Panels folder are 
  1070. loaded in alphabetical order.  Any INITs present at the root level of 
  1071. the System Folder are loaded after that.  This order of loading is 
  1072. important if an extension is dependent on the presence of another 
  1073. extension.  For example, if an INIT resource in an INIT file named 
  1074. 'SpeakAll' is dependent on the presence of the 'Speech Manager' 
  1075. extension, it either needs to have its name changed to something that 
  1076. sorts after 'Speech Manager' or it has to be located in the Control 
  1077. Panels folder, since extensions in the Control Panels folder load 
  1078. after extensions in the Extensions Folder. 
  1079.  
  1080. In system 6 the Extensions Folder and Control Panels Folders don't 
  1081. exist.  Extensions are simply loaded in alphabetical order from the 
  1082. root level of the System Folder.
  1083.  
  1084. --
  1085. [2] Should I write an INIT?
  1086.  
  1087. System extensions are not easy to write.  If this is your first 
  1088. attempt at Mac programming, the answer to this question is NO.  Many 
  1089. experienced Mac programmers have never written one and don't intend 
  1090. to.  
  1091.  
  1092. There are a number of other ways to add functionality without writing 
  1093. an extension.  If you want to add functionality to a single 
  1094. application then think about writing an FKEY.  These are invoked by 
  1095. hitting cmd-shift-number and perform an action at that time only.  
  1096. The standard screen shot (cmd-shift-3) is one example.
  1097.  
  1098. Another user-invokable means of adding functionality is plug-in 
  1099. modules.  A number of commercial software packages support plug-ins 
  1100. that can add functionality in a straightforward manner.  This 
  1101. includes PhotoShop, Quark Express, Hypercard and others.
  1102.  
  1103. Another means of adding functionality is the use of a background-only 
  1104. application, AKA faceless-background application (fba).  Fbas are 
  1105. applications without a user interface.  One type of fba is known as 
  1106. an application extension.  These are applications whose resource 
  1107. files are of type 'appe'.  They are placed in the extensions folder 
  1108. (or the Startup Items Folder) and are started up after INIT time.  
  1109. They can communicate with other processes by Apple Events and by 
  1110. Gestalt selectors.  If you don't need to patch a trap then an fba may 
  1111. be the way to add functionality to the system.  Since an fba runs as 
  1112. a normal process there are some things that it can do that system 
  1113. extensions cannot do (or at least cannot do safely), like launch 
  1114. applications and send and receive Apple Events.  An INIT resource in 
  1115. the resource fork of an application extension in the Extensions 
  1116. Folder will load normally at INIT time.  See issue 9 of develop and 
  1117. the Tech Note PS 2 - Background-Only Applications for more info.
  1118.  
  1119. Also consider an application that is started up by being placed in 
  1120. the startup items folder.  The Screen Saver 'Dark Side of the Mac' is 
  1121. written in this way.  Screen Savers are traditionally written as 
  1122. extensions because extensions can have access to the mouse location 
  1123. and all keyboard events.  However an intelligently written 
  1124. application can do the same and be more compatible.  
  1125.  
  1126. If none of these things seems like it will work for you and you are 
  1127. thinking something like 'I want X to happen every time a resource is 
  1128. loaded', or otherwise add to or replace the system's functionality in 
  1129. some way then an extension is probably what you need.
  1130.  
  1131. Remember that when developing system extensions you will be working 
  1132. without a net.
  1133.  
  1134. --
  1135. [3] Can I write an INIT that makes the application menu into a 
  1136. hierarchical menu?
  1137.  
  1138. Every couple of weeks someone posts a message on 
  1139. comp.sys.mac.programmer entitled 'Neat idea for an init'.  These 
  1140. posts go on to describe some non-programmer's idea of a great INIT.  
  1141. Invariably these posts fall into two groups: those that have already 
  1142. been done, and those that should never be done.  Think long and hard 
  1143. about the design of an extension before starting to write it.  
  1144. Consider your target audience.  If it's only yourself then you can do 
  1145. what you want.  My first couple of extensions were just tests to see 
  1146. if I could actually do it.  The answer to the above question is: 
  1147. Maybe you can but probably you shouldn't.
  1148.  
  1149. --
  1150. [4] Do I need to know assembler to write an extension?
  1151.  
  1152. Yes.  Strictly speaking, the simplest extension that just beeps at 
  1153. startup and doesn't hang around past INIT time requires no assembler.  
  1154. However, any extension that does anything useful will require some 
  1155. assembler in order to patch a trap or install a jGNEFilter.  The 
  1156. extension can be written mostly in a high level language like C or 
  1157. Pascal, but there will be bits and pieces that need to be written in 
  1158. assembler to keep the stack happy or to access parameters passed in 
  1159. registers.  Hopefully there will be enough sample code in this 
  1160. document to get you on your way if your assembler is weak.
  1161.  
  1162. You will often need to inspect the disassembled source of your 
  1163. extension.  If your development environment doesn't allow this the 
  1164. ResEdit Code Viewer will also allow you to inspect code resources.  
  1165. It can be found at ftp://ftp.apple.com/dts/mac/tools/resedit/resedit-
  1166. extensions.hqx.
  1167.  
  1168. --
  1169. [5] Can you show me a sample INIT?
  1170.  
  1171. Here's the code for the 'Hello World' of INITs.
  1172.  
  1173. void main(void)
  1174. {
  1175.    SysBeep( 5 );
  1176. }
  1177.  
  1178. Not very complicated is it?  There are a number of additional things 
  1179. that are required to make this work:
  1180.  
  1181. 1) Set the project type to code resource.
  1182. 2) Set the resource type to 'INIT'.
  1183. 3) Set the resource ID to something (>= 128), and set the resource 
  1184. name if desired.
  1185. 4) Set the resource attributes to 'System Heap'.
  1186. 5) Set the resource attributes to 'Locked'.
  1187. 6) Set the filetype of the built code resource file to 'INIT' with 
  1188. any creator signature.
  1189. 7) Set the filename of the built code resource file to 'Hello World'.
  1190.  
  1191. Let me explain what each of these things does.  
  1192.  
  1193. 1)  Because you're building a standalone code resource your compiler 
  1194. needs to know this.  This is how the compiler knows to use A4 
  1195. addressing, rather than the A5 addressing used in applications.
  1196.  
  1197. 2)  As mentioned above, extensions are code resources of type 'INIT'.  
  1198.  
  1199. 3)  Like any other resources they have IDs and can have names.  
  1200.  
  1201. 4)  Setting the system heap flag places the code resource in the 
  1202. system heap.  While not strictly required for this sample, in most 
  1203. other extensions we will want the code resource to remain in the 
  1204. system heap so this flag must be set.  During the process that loads 
  1205. and executes INITs a small heap is created.  Any memory allocation 
  1206. done by the INIT will, by default occur in this heap.  Also any 
  1207. resources read into memory will, by default, go into this heap.  If 
  1208. the system heap flag isn't set for the INIT itself then the INIT will 
  1209. be loaded into this temporary heap.  When the INIT exits the heap is 
  1210. disposed and anything in it is lost.  If an INIT intends to stay 
  1211. around past INIT time then it must have the system heap flag set.
  1212.  
  1213. 5)  The code resource should never move in memory so the Locked bit 
  1214. is set.  When a resource with the Locked bit is loaded into memory it 
  1215. is loaded as low in the heap as possible.  This is what we want since 
  1216. the INIT resource will never be unlocked.  It is poor design to not 
  1217. set the Locked bit and to rely on the INIT to lock itself.  In that 
  1218. case the INIT will not be loaded low in the system heap.  This isn't 
  1219. fatal but will lead to fragmentation of the system heap.  
  1220.  
  1221. Some INITs try to use MoveHHi/HLock to move themselves or associated 
  1222. resources high in the system heap.  MoveHHi is disabled for the 
  1223. system heap.  Since the system heap is dynamically sizable the 
  1224. concept of the top of the heap is invalid.  For this reason MoveHHi 
  1225. does nothing when the handle being referred to is within the system 
  1226. heap.  
  1227.  
  1228. 6)  The filetype of 'INIT' gives you the generic extension icon, and 
  1229. of course allows the extension to load and execute at INIT time.
  1230.  
  1231. 7)  Set the file name to something like 'Hello World'.
  1232.  
  1233. Once these things have been done you can build the code resource and 
  1234. drag its file to the System Folder.  The Finder should place it in 
  1235. the Extensions Folder for you and it should have the generic 
  1236. extension icon.  When you restart you will hear the beep when the 
  1237. extension is loaded.
  1238.  
  1239. Every extension must have a routine called 'main'.  When the INIT 
  1240. resource is loaded into memory during INIT time the system jumps to 
  1241. the beginning of the code resource.  The header of the code resource 
  1242. will normally contain a branch instruction that branches to the main 
  1243. routine.  This routine does whatever it needs to do and then returns.  
  1244. In this 'Hello World' extension all that the main routine does is 
  1245. call SysBeep.  In more substantial extensions the main routine will 
  1246. do things like patch traps, install gestalt selectors, and load 
  1247. resources into memory.
  1248.  
  1249. --
  1250. [6] Can I have global variables in my INIT?
  1251.  
  1252. Yes you can.  The Think environment and the CodeWarrior environment 
  1253. use A4-based addressing for global variables in code resources.  The 
  1254. base address of the extension is found in register A0 on entry to the 
  1255. extension, and routines are provided to save this value and to set up 
  1256. and restore register A4 when the INIT is entered later.  (In fact the 
  1257. standard header installed by Think C in code resources loads the 
  1258. address of the code resource into A0 by use of pc-relative 
  1259. addressing.)  See the A4-Addressing section of your development 
  1260. environment's manual for more information.  
  1261.  
  1262. When writing extensions with the MPW compilers you may need to use an 
  1263. A5-based method for accessing global variables.  See the Apple tech 
  1264. note 'StandAlone Code, ad nauseam' (#256) for more information on 
  1265. this method.  ftp://ftp.apple.com/dts/mac/tn/platforms.tools.pt/pt-
  1266. 35-stand-alone-code.hqx 
  1267.  
  1268. and 
  1269.  
  1270. "Another take on Globals in Standalone Code", Keith Rollin
  1271. ftp://ftp.apple.com/dts/mac/docs/develop/develop.12.code/globals-in-
  1272. standalone-code.hqx
  1273.  
  1274. Here is some sample code using the Think C routines to illustrate 
  1275. this:
  1276.  
  1277. /****Main*****************************************************/
  1278. void 
  1279. main(void)        //Main entry point of the extension
  1280. {
  1281.    void     *pToMe;
  1282.    Boolean  initedOK;
  1283.  
  1284.    pToMe = GetA0();     //Save our address locally
  1285.  
  1286.    RememberA0();        //Save our base address
  1287.    SetUpA4();           //Set up A4-based addressing
  1288.  
  1289.    initedOK = InitAll();   //Patch traps etc.
  1290.    if ( initedOK )
  1291.    {
  1292.                      //Make sure we stay around
  1293.       DetachResource( RecoverHandle( pToMe) );  
  1294.    }
  1295.  
  1296.    RestoreA4();         //Reset A4 to its value on entry
  1297. }
  1298.  
  1299. This code sample also illustrates one method extensions can use to 
  1300. remain in memory after INIT time.  Since extensions are code 
  1301. resources they will be removed from memory when their resource files 
  1302. are closed.  This happens when the main routine exits.  To avoid 
  1303. this, DetachResource must be called with the handle to the code 
  1304. resource.  One common mistake with this is not having the code 
  1305. resource marked system heap.  If it's not marked system heap it will 
  1306. be lost when the temporary heap is destroyed, whether it was detached 
  1307. or not.  The GetA0 routine used above is defined in the tips section 
  1308. farther down in this document.  Here are a few other methods for an 
  1309. extension to detach itself:
  1310.  
  1311. void 
  1312. main(void)     //Another method
  1313. {
  1314.    asm
  1315.    {
  1316.       RecoverHandle     //A0 already holdss our address
  1317.       move.L   A0, -(A7)   //DetachResource is stack-based
  1318.       DetachResource    //so push A0 onto the stack
  1319.    }
  1320. }
  1321.  
  1322. void 
  1323. main(void)     //This method uses no assembler
  1324. {
  1325.    DetachResource( Get1Resource( 'INIT', kOurResID ) );
  1326. }
  1327.  
  1328. --
  1329. [7] How do I debug an INIT?
  1330.  
  1331. Debugging is generally the most time consuming, difficult, and all-
  1332. around pain-in-the-neck part of producing good code.  That goes 
  1333. double for INITs.  Unfortunately many parts of INITs must be debugged 
  1334. with low level debuggers.  The low level debuggers that I know about 
  1335. are MacsBug, TMON, and Jasik's Debugger.  MacsBug is free and is 
  1336. available at ftp://ftp.apple.com/dts/mac/tools/macsbug/macsbug-6-
  1337. 5d6.hqx.  The two other low level debuggers are commercialware.  
  1338. Jasik's debugger has the ability to do source level debugging of code 
  1339. resources, like system extensions.
  1340.  
  1341. In most cases, your low level debugger of choice will load before 
  1342. INIT time so it can be used to debug initialization of INITs.  One 
  1343. exception to this is Jasik's Debugger, which loads in two parts.  One 
  1344. of these is an extension that must load before your extension.  
  1345.  
  1346. The debugger can be invoked by calling the Debugger() or DebugStr() 
  1347. traps.  Placing these trap calls in your code will drop you into the 
  1348. low level debugger so that you can step through your code and inspect 
  1349. registers or memory as needed.
  1350.  
  1351. One useful technique is to take advantage of Macsbug's ability to 
  1352. process commands after a semicolon in a DebugStr call.  The following 
  1353. function can display information that you would otherwise have to 
  1354. hunt down using hex offsets:
  1355.  
  1356. pascal void SomeFunction (arguments)
  1357. {
  1358.     // ...
  1359.  
  1360.     asm { MOVE.L fooP, A0 }      // fooP can be any type
  1361.     asm { MOVE.L sizeof(*fooP), D0 }
  1362.     DebugStr ("\p ; dm rA0 rD0");   // dump (*fooP) in hex
  1363.  
  1364.     // ...
  1365. }
  1366.  
  1367. If you haven't placed Debugger() calls in your code then you will 
  1368. have to set a breakpoint in order to step through any trap patches or 
  1369. other parts of your extension.  Here are a couple of methods to do 
  1370. that.  If you have patched a trap, say GetResource, if you drop into 
  1371. MacsBug and type 'il GetResource' MacsBug will begin to disassemble 
  1372. at your patch.  You can then set a breakpoint by typing 'br 
  1373. GetResource' or br theaddress' where theaddress is the address in hex 
  1374. of your patch or some part of it.  Type 'brc' when you want to clear 
  1375. all breakpoints.  Using the A-trap commands will also work.  'atb 
  1376. GetResource' will set a break and 'atc' will clear all A-trap 
  1377. breakpoints.
  1378.  
  1379. If you want to set a breakpoint in some other part of your extension, 
  1380. say in a jGNEFilter, then you need another way of finding its 
  1381. location in memory.  In MacsBug type 'hx syszone^' or just 'hx' to 
  1382. set the current heap to the system heap (where your extension is 
  1383. located).  Type 'br ' (don't hit return yet) and then type cmd-D to 
  1384. view the names of all the routines in the system heap that were 
  1385. compiled with MacsBug names turned on (like yours, right?)  Scroll 
  1386. down until you find the name of your routine.  Hit enter and the 
  1387. command line should look like 'br yourRoutineName'.  Hit enter again 
  1388. and the breakpoint will be set.  You can also simply type 'br 
  1389. yourRoutineName' and MacsBug will find it for you.  The zone must be 
  1390. set to the zone containing the routine that you want to break on for 
  1391. MacsBug to find it, so make sure to set the zone to the system zone.
  1392.  
  1393. Identifying your extension in the system heap is dependent on 
  1394. compiling it with the MacsBug symbols option turned on.  This inserts 
  1395. Ascii versions of the names of each function in the compiled code in 
  1396. such a way the MacsBug , and other debuggers can find these names.  
  1397. Jasik's debugger uses a different method for identifying your code 
  1398. that is based on SYM files, which are generated by your compiler.  
  1399. The SYM files allows Jasik's debugger to do source level debugging of 
  1400. INITs and other code resources.
  1401.  
  1402. I have used a two-project method, when developing INITs and other 
  1403. code resources, that helps to cut down debugging time.  Any extension 
  1404. consists of essentially two parts: the initialization portion and the 
  1405. implementation portion.  The initialization portion detaches the 
  1406. resource as described above, shows the icon, and often patches traps.  
  1407. The implementation portion contains the actual trap patches.  It is 
  1408. quite possible, and desirable, to test the implementation portion in 
  1409. the context of an application, rather than as an INIT.  To accomplish 
  1410. this your project consists of three parts, which for a simple case 
  1411. would be three files.
  1412.  
  1413. TesterApp Project:
  1414.    SetUpApplication.c   Simple application shell that sets up 
  1415.                the trap patches and provides a  
  1416.                mechanism to call the traps
  1417.    TrapPatches.c     Code for the trap patches
  1418.  
  1419. INIT Project:
  1420.    SetUpINIt.c       Standard INIT setup; contains main  
  1421.                entry point; patches all necessary  
  1422.                traps
  1423.    TrapPatches.c     Code for the trap patches; same file as 
  1424.                in the TesterApp Project
  1425.  
  1426. The mechanism for calling the traps in SetUpApplication.c is usually 
  1427. a menu item.  In some cases it might be a dialog with several 
  1428. buttons, each of which calls a particular trap.  It isn't always 
  1429. necessary to patch traps in your TesterApplication.  Simply calling 
  1430. the routines that implement the guts of the trap patches will often 
  1431. be just as good.  Having two projects, one that builds the tester 
  1432. application and the other that builds the extension, allows you to 
  1433. save time debugging and to be able to build the extension at any 
  1434. time.
  1435.  
  1436. Writing and testing extensions involves multiple rounds of 
  1437. 'compiling-installing the INIT-rebooting-Stepping through the INIT in 
  1438. a low level debugger'.  Use of the two-project method will cut down 
  1439. this time.
  1440.  
  1441. --
  1442. [8] How do I write a Control Panel-INIT combination?
  1443.  
  1444. System extensions generally have no interface.  They do what they do 
  1445. quietly and the user doesn't want to hear from them.  In many cases 
  1446. the user needs to set certain preferences.  The natural mechanism for 
  1447. this is to couple a control panel with an INIT.  The problem of 
  1448. course is how does the control panel communicate the changes to the 
  1449. INIT.  I won't discuss the general mechanisms of control panel 
  1450. authoring here (see NIM: More Macintosh Toolbox, Chapter 8), but 
  1451. there are several mechanisms available for communicating between 
  1452. extensions and control panels.
  1453.  
  1454. The simplest mechanism and one that will work in the vast majority of 
  1455. cases is for the extension to install a Gestalt selector.  This 
  1456. selector returns the address of a block of memory that holds 
  1457. variables that control the actions of the extension.  The control 
  1458. panel calls the Gestalt selector, retrieves the address of the memory 
  1459. block, and alters the values stored in the block as needed.  In some 
  1460. cases the memory block can contain a function pointer to a function 
  1461. in the extension that needs to be called from the control panel.  
  1462. Here is some sample code:
  1463.  
  1464. typedef struct CommonInfo{
  1465.    void     (*ResetINIT) (void);//function pointer to reset 
  1466.                            //func
  1467.    Boolean  On;
  1468. };
  1469.  
  1470. #define kSignature 'BLAH'  //Should be the sig of the INIT
  1471.  
  1472. static CommonInfo    gInfo;
  1473.  
  1474. /**InstallGestaltSelector****************************************/
  1475. //In the INIT; runs at INIT time
  1476. OSErr
  1477. InstallGestaltSelector(void)
  1478. {
  1479.    OSErr    err;
  1480.  
  1481.    err = NewGestalt( kSignature, OurSelector );
  1482.    
  1483.    if ( err == noErr )
  1484.    {
  1485.       gInfo.ResetINIT = (void *) ResetFunction;
  1486.       gInfo.On = TRUE;
  1487.    }
  1488.  
  1489.    return err;
  1490. }
  1491.  
  1492. /**OurSelector**************************************************/
  1493. //In the INIT
  1494. pascal OSErr 
  1495. OurSelector( OSType theSelector, long *theResponse )
  1496. {
  1497.    SetUpA4();
  1498.  
  1499.    *theResponse = (long) &gInfo;
  1500.    
  1501.    RestoreA4();
  1502.  
  1503.    return noErr;
  1504. }
  1505.  
  1506. /**ResetFunction***********************************************/
  1507. //In the INIT
  1508. void 
  1509. ResetFunction(void)
  1510. {
  1511.    SetUpA4();
  1512.  
  1513.    //Do something here
  1514.    
  1515.    RestoreA4();
  1516. }
  1517.  
  1518. /**Close********************************************************/
  1519. //In the Control Panel
  1520. void
  1521. Close( Boolean IsOn )
  1522. {
  1523.    long        result;
  1524.    CommonInfo     *Info;
  1525.    
  1526.    //Get address of globals struct from init
  1527.    err = Gestalt( kSignature, &result );
  1528.    if ( err == noErr )
  1529.    {
  1530.       Info = (GlobalsType *) result;
  1531.       Info->On = IsOn;        //Reset OnOff Boolean
  1532.       ( * (*Info).ResetINIT) (); //Jump to INIT
  1533.    }
  1534. }
  1535.  
  1536. If it is possible for an error to occur that prevents the extension 
  1537. from resetting itself the ResetFunction should return an error code 
  1538. and the control panel should display an alert indicating the problem.
  1539.  
  1540. Two additional methods are sometimes used to accomplish communication 
  1541. between an extension and a control panel:  
  1542.  
  1543. The first of these is to write a driver that is installed by the 
  1544. extension.  The driver holds global variables and will return the 
  1545. address of the block of memory holding these variables in response to 
  1546. i/o, status, or control calls to the driver.  Sample code showing how 
  1547. to do this is available in a package called driver-22 written by Pete 
  1548. Resnick to be found at:
  1549. ftp://sumex-aim.stanford.edu/info-mac/dev/src/driver-22-c.hqx.gz
  1550.  
  1551. The second additional method is to use the PPC toolbox for direct 
  1552. communication.  There is sample code demonstrating this at: 
  1553. ftp://ftp.apple.com/dts/mac/sc/7.0.samples/init-cdev.hqx.
  1554.  
  1555. --
  1556. [9] How do I capture keystrokes?
  1557.  
  1558. This is accomplished by writing a jGNEFilter function.  jGNEFilter 
  1559. functions are called from GetNextEvent and WaitNextEvent just before 
  1560. those traps return to an application.  They are passed a pointer to 
  1561. the event record that will be returned to the application.  In order 
  1562. to capture keystrokes the jGNEFilter would simply check the what 
  1563. field of the event record looking for keyboard events and would 
  1564. extract the information from the message field if one were found.  
  1565.  
  1566. The jGNEFilter mechanism is very powerful and is one way that 
  1567. screensavers can be implemented.  The filter would save the time of 
  1568. any keyboard events and would compare the location of the mouse 
  1569. against its previous location on null events.  If the preset time had 
  1570. elapsed during which no keyboard events or mouse movement had 
  1571. occurred then the screen saver would activate.  A more complete 
  1572. discussion of the jGNEFilter is in the next section.
  1573.  
  1574. If you are thinking of patching WaitNextEvent or PostEvent in order 
  1575. to capture keystrokes or other events, don't.  Use a jGNEFilter 
  1576. instead.  It's easier, it's compatible.  It's even documented.  See 
  1577. the Tech Note 'GetNextEvent; Blinking Apple Menu' (#85).
  1578.  
  1579. ftp://ftp.apple.com/dts/mac/tn/toolbox.tb/tb-11-getnextevent.hqx
  1580.  
  1581. -- 
  1582. Brian  Stern  :-{)}
  1583. Toolbox commando and Menu bard
  1584. Jaeger@fquest.com
  1585.  
  1586. ---------------------------
  1587.  
  1588. >From Jaeger@fquest.com (Brian Stern)
  1589. Subject: INIT Writing FAQ [2-3]
  1590. Date: 28 Oct 1994 00:42:44 GMT
  1591. Organization: The University of Texas at Austin, Austin, Texas
  1592.  
  1593. --
  1594. [10] How can my extension get time periodically?
  1595.  
  1596. Installing a jGNEFilter is one method of obtaining periodic time.  
  1597. Since the jGNEFilter mechanism is dependent on the event processing 
  1598. mechanism, one problem is that no events may be posted if the mouse 
  1599. is held down for an extended time.  
  1600.  
  1601. If your INIT only needs to get time every once in a while then I 
  1602. recommend that it only do its thing on null events.  On other events 
  1603. it should just return.  This will have the least impact on the 
  1604. machine's performance.  
  1605.  
  1606. Remember that your jGNEFilter will be called for EVERY event on the 
  1607. machine.  Do not do a lot of processing on every event or you will be 
  1608. slowing down the machine needlessly.  Another way to reduce the 
  1609. frequency of your extension's processing is to use a simple timer, 
  1610. based on TickCount().  In this way your processing is only done, say, 
  1611. every 30 or 60 ticks, on null events of course.
  1612.  
  1613. Sample code demonstrating jGNEFilters can be found in a package 
  1614. called jGNE Helper by Pete Gontier in the alt.sources.mac archive at: 
  1615. ftp://ftpbio.bgsu.edu/ftp/pub/alt.sources.mac/vol-
  1616. 01/jgnehelper.cpt.hqx.  
  1617.  
  1618. Another sample in MPW assembler is at 
  1619. ftp://ftp.apple.com/dts/mac/sc/snippets/toolbox/jgnefilter.hqx.
  1620.  
  1621. Here's another example that works in Think C:
  1622.  
  1623. static   ProcPtr  gOldGNEFilter;
  1624.  
  1625. /****InstallFilter***********************************************/
  1626. //Run this at INIT time
  1627. void
  1628. InstallGNEFilter (void)
  1629. {
  1630. /*Save the ProcPtr to the previous jGNEFilter and insert ours*/
  1631.    gOldGNEFilter = JGNEFilter;
  1632.    JGNEFilter = (ProcPtr) StripAddress( FilterProc );
  1633.  
  1634.  }
  1635.  
  1636. /****FilterProc**************************************************/
  1637.  
  1638. void
  1639. FilterProc(void)
  1640. {
  1641.    EventRecord    *theEvent;
  1642.    long        SaveD0;
  1643.    
  1644.    theEvent = GetA1();  //Move the eventPtr to a variable
  1645.    SaveD0 = GetD0(); //Preserve D0
  1646.  
  1647.    SetUpA4();
  1648.  
  1649.    switch ( (*theEvent).what ) {
  1650.       case nullEvent:
  1651.          //Do our thing
  1652.          break;
  1653.          
  1654.       case keyDown:
  1655.          //Do something else
  1656.          break;
  1657.    }
  1658.    
  1659.    //Execute the previous jGNEFilter
  1660.    SetA1( theEvent );   //Restore A1 for the next jGNEFiler
  1661.    SetD0( SaveD0);      //Restore D0
  1662.    SetA0( gOldGNEFilter ); //Put next jGNEFilter in A0
  1663.    
  1664.    RestoreA4();
  1665.  
  1666.    asm{
  1667.       Unlk     A6
  1668.       Move.W   D0, 4(A7)   ;Set Function result on the stack
  1669.       JMP      (A0)     ;Jump to the next jGNEFilter
  1670.    }
  1671.  
  1672. }
  1673.  
  1674. Since a jGNEFilter has access to the actual event record that will be 
  1675. returned to the application, the filter can alter the event.  The 
  1676. most common thing to do is to 'cancel' an event by changing it to a 
  1677. null event (Ex. theEvent->what = nullEvent).  In this case it should 
  1678. also set the value in register D0 to False, or zero.
  1679.  
  1680. Here are some additional methods for an extension to get time 
  1681. periodically:
  1682.  
  1683. If your extension needs more frequent or regular time then can be 
  1684. provided by a jGNEFilter then you can install a VBL task or a time 
  1685. manager task.  Since these run at interrupt time they cannot do 
  1686. anything that could move or purge memory.  Other methods include 
  1687. patching a trap that is called frequently, like SetPort.
  1688.  
  1689. A faceless Notification Manager request is another method to get 
  1690. time.  This is a request that has all the fields in the notification 
  1691. record set to NULL except the nmResp field that holds the address of 
  1692. your routine to be executed.  Your notification response routine will 
  1693. be called soon and will be able to move memory.  If necessary the 
  1694. routine can reinstall itself.  This technique is useful for tasks 
  1695. that need to be executed once or intermittently.  For those tasks 
  1696. that need to be executed regularly use one of the other techniques.
  1697.  
  1698. You could of course have a faceless NM request that is installed by a 
  1699. VBL task or a time manager task.  
  1700.  
  1701. Use of a faceless background application in concert with an extension 
  1702. is yet another method to get time.  The fba would do its work on its 
  1703. null events.
  1704.  
  1705. --
  1706. [11] How should an INIT manage memory?
  1707.  
  1708. In general, at INIT time extensions will want to allocate memory in 
  1709. the system heap.  If you are allocating pointers or handles, use the 
  1710. SYS variants, like NewHandleSys() and NewPtrSys().  It is a common 
  1711. error to forget this and then to wonder why the INIT crashes.  If you 
  1712. call NewHandle at INIT time, the handle will be allocated in the 
  1713. temporary heap allocated for your extension.  If your INIT attempts 
  1714. to use it after INIT time the temporary heap will be long gone, along 
  1715. with any handles or pointers that had been allocated in it.  Any 
  1716. attempt to use handles or pointers that no longer exist are 
  1717. predictably unpredictable :-) 
  1718.  
  1719. NewHandle and NewPtr will allocate their memory blocks in the system 
  1720. heap if the zone has been set to the system heap, as shown in the 
  1721. next paragraph.
  1722.  
  1723. If you need to read in resources you can ensure that they go into the 
  1724. system heap with something like the following code:
  1725.  
  1726. THz   saveZone = GetZone();
  1727.    SetZone( SystemZone() );
  1728.    //read in resources
  1729.    SetZone( saveZone );
  1730.  
  1731. You will of course need to detach the resources if they need to 
  1732. remain in memory after your extension exits.  The resource file 
  1733. containing your extension will be closed when your extension exits.
  1734.  
  1735. If you need to read resources into memory after INIT time you need to 
  1736. decide which heap they should go into, either the application heap or 
  1737. the system heap.  It's a bit hard to make a specific recommendation 
  1738. on this but if the resource is something that the application is 
  1739. expecting to be read in then it should go into the application heap.  
  1740. This would include things like WIND resources in a trap patch to 
  1741. GetNewWindow().  The problem of course is that the application heap 
  1742. may not have enough room.  However, if the resources are private to 
  1743. the extension then they should go into the system heap.
  1744.  
  1745. It should go without saying that you should always check the error 
  1746. codes on memory allocating calls and resource manager calls.  If your 
  1747. extension is doing something in response to a user action, say making 
  1748. a network connection, then it is appropriate to report such errors.  
  1749. In many cases however, your extension will simply do nothing in the 
  1750. case of out of memory errors or missing resource errors.  It is best 
  1751. to attempt to allocate all of these things at INIT time and if 
  1752. unsuccessful to bail out then.
  1753.  
  1754. As mentioned above, MoveHHi doesn't work in the system heap.  If you 
  1755. intend to allocate a handle that will remain locked for extended 
  1756. periods, then call ResrvMem before allocating and locking the handle.  
  1757. This will place the handle low in the system heap and help to prevent 
  1758. heap fragmentation. 
  1759.  
  1760. Many toolbox calls are documented as not moving or purging memory and 
  1761. as being safe to call at interrupt time.  If you are patching one of 
  1762. these traps then you must preserve this property.  You are guaranteed 
  1763. to cause other software to crash if you don't, and your users will 
  1764. hate you (once they figure out that it's you).  Be aware that the 
  1765. only memory manager routine safe to call under these circumstances is 
  1766. BlockMove. Also be aware that it is unsafe to access an unlocked 
  1767. handle at interrupt time.  It is possible that the memory manager is 
  1768. in the midst of moving it from one place to another in the heap, and 
  1769. the master pointer may not be updated yet.
  1770.  
  1771. --
  1772. [12] How do I get my INIT to turn itself off?
  1773.  
  1774. An extension might want to turn itself off at INIT time based on its 
  1775. preferences setting, or based on a key being pressed or the mouse 
  1776. button being pressed, or due to an error during initialization.  
  1777. Extensions usually show an icon with a red X through it in this case.  
  1778. An extension might also want to turn itself off temporarily after 
  1779. INIT time in response to its Control Panel.  For instance GateKeeper 
  1780. has an on/off switch that turns off virus checking for a set time.
  1781.  
  1782. The strategy for temporarily turning off an extension is simply to 
  1783. set a global flag and to check it from within the trap patches or 
  1784. other parts of the extension.  If the flag is off then the trap patch 
  1785. simply executes the previous trap.  It is generally unsafe to unpatch 
  1786. or patch traps after INIT time from an extension.  The reason for 
  1787. this is that if another extension patches the same trap after you 
  1788. have, then it will be jumping to your patch when it has completed its 
  1789. work.  If you have removed your patch then this calling chain will be 
  1790. disrupted and bad things will happen.  Also, the Finder patches 
  1791. various traps when it loads, which is after INIT time.  Disrupting 
  1792. those patches would be a very bad thing.
  1793.  
  1794. If an extension determines at INIT time that it isn't going to stay 
  1795. around then it shouldn't call DetachResource on itself.  It's best 
  1796. that your extension determine that anything it's dependent on, such 
  1797. as resources, specific system Managers, and sufficient memory, are 
  1798. present *before* it starts to patch traps and install drivers, 
  1799. jGNEFilters and so on.  It would be a very bad idea for an extension 
  1800. to not detach itself after it had already patched a trap if the trap 
  1801. patch resided in the extension.
  1802.  
  1803. Many extensions use a particular key press as a signal to indicate 
  1804. that the user wants them not to run.  Of course the system uses the 
  1805. shift key as a signal not to turn on any extensions so you can't use 
  1806. that.  Some extensions use the option or command keys for this 
  1807. purpose.  The problem with using those keys is that every time I 
  1808. rebuild the desktop those extensions are needlessly inactivated.  I 
  1809. recommend that the space bar be used for this purpose.  Here's some 
  1810. sample code:
  1811.  
  1812.  Boolean
  1813.  SpaceBarIsDown(void)
  1814.  {
  1815.    KeyMap      theKeys;
  1816.  
  1817.    GetKeys( theKeys );
  1818.  
  1819.    if ( theKeys[1] & 0x00000200 )//Check for spacebar
  1820.       return TRUE;
  1821.    else
  1822.       return FALSE;
  1823.  
  1824.  }
  1825.  
  1826. --
  1827. [13] How do I get my INIT to show it's icon like all the other cool 
  1828. inits do?
  1829.  
  1830. This is easy.  There is code available that does this for you.  Get a 
  1831. package written by Jim Walker called ShowIcon7 at:
  1832. ftp://mac.archive.umich.edu/mac/development/source/showicon7.sit.hqx
  1833.  
  1834. You use it essentially as a plug-in.  Just pass in the icon's 
  1835. resource ID and it does everything for you.  It also shows how to set 
  1836. up an A5 world in an extension.  You might also take a look at Dair 
  1837. Grant's Extension shell package.  This one shows how to do animated 
  1838. icons.
  1839.  
  1840. If your extension decides that it can't install itself then it passes 
  1841. the resource ID of an icon that has a red X through it to the 
  1842. showicon7 code resource.
  1843.  
  1844. Some extensions include the ShowIcon code within their own code 
  1845. resources.  This code is only about 1K but it seems pointless to me 
  1846. for this code to sit in the system heap when it doesn't have to be.  
  1847. Use it as a plug-in for your extensions.
  1848.  
  1849. --
  1850. [14] How do I show a dialog from my INIT?
  1851.  
  1852. First of all, I hate windows of any kind during the startup process.  
  1853. If all you want to do is show an alert then use the Notification 
  1854. Manager.  Your alert will show up when the Finder starts but the user 
  1855. will see it and will get whatever message you need to send.  
  1856.  
  1857. The problem I have with windows at INIT time is that they slow down 
  1858. this process and require user interactivity in a process that 
  1859. shouldn't do so.  Consider the computer that is on 24 hours a day 
  1860. doing something important unattended.  The power goes off and when it 
  1861. comes back on the machine reboots.  The user returns several hours 
  1862. later to find that the machine is still in the middle of its startup 
  1863. because your alert is waiting for a response.  Consider also the 
  1864. hapless INIT writer who has to reboot his machine 20 times a day.  
  1865. Your INIT will not last long on my, um, his machine.
  1866.  
  1867. One additional annoyance is that you need to call InitWindows to show 
  1868. your window and this erases all the nice INIT icons on the screen.  I 
  1869. hate that.
  1870.  
  1871. Here are a few possible alternatives.  
  1872.  
  1873. * Play a sound or use the Speech Manager to communicate the 
  1874. information.  
  1875.  
  1876. * Show a different icon during startup to indicate an error.  An icon 
  1877. with a red X through it is one way to do this.  You could also use 
  1878. animated icons.
  1879.  
  1880. * If you must put up an alert then use a timer so that the alert goes 
  1881. away by itself, even if the OK button isn't clicked.
  1882.  
  1883. * If you need to interact with the user to get some information, say 
  1884. a password for a network connection, then do this once and save the 
  1885. results in a preferences file.  Provide a Control Panel to change the 
  1886. information.  Think of Control Panels as the interface for 
  1887. extensions.
  1888.  
  1889. * Store descriptions of any errors that occur in a preferences file.  
  1890. Have the Control Panel display this information.  Remember to clear 
  1891. this information on each restart and to indicate to the user by sound 
  1892. or icon that an error has occurred.
  1893.  
  1894. * If you need to communicate error information to the user after INIT 
  1895. time then you should definitely use the Notification Manager.  For 
  1896. example, MacSLIP uses the NM to show an alert indicating that the 
  1897. carrier has been lost.
  1898.  
  1899. If you still want to show a dialog at INIT time then you need to set 
  1900. up an A5 world first.  The ShowIcon7 code mentioned above shows how 
  1901. to do this.  Also see the Tech Note 'Stand-Alone Code' (#256) for an 
  1902. explanation and sample code for this and 'Giving the (Desk)Hook to 
  1903. INITs' (247) discusses a bug that can appear when showing windows 
  1904. from extensions.
  1905. ftp://ftp.apple.com/dts/mac/tn/operating.system.os/os-02-deskhook-
  1906. and-init.hqx
  1907.  
  1908. If you do use the Notification Manager from an extension to indicate 
  1909. that the extension couldn't load you should use a self-disposing 
  1910. Notification request.  There are several strategies for doing this.  
  1911. I have some code samples for this that will be (have been?) posted to 
  1912. alt.sources.mac soon.
  1913.  
  1914. --
  1915. [15] How do I maintain compatibility with future systems?
  1916.  
  1917. This is tough, and the short answer is that you probably don't.  
  1918. You'll notice that Apple comes out with new versions of its 
  1919. extensions with each revision of the system.  Apple's extensions also 
  1920. eventually disappear as their functionality is rolled into the 
  1921. system.  In all likelihood you'll have to come out with new versions 
  1922. of your extensions as new versions of the system come out as well.
  1923.  
  1924. Having said all that, there are things you can do to minimize this 
  1925. problem.  Here are a few suggestions:
  1926.  
  1927. * Minimize your reliance on undocumented features of the system.
  1928.  
  1929. * Minimize your reliance on low memory globals.  Use the Universal 
  1930. Header access 'functions' for accessing the low memory globals if 
  1931. necessary.
  1932.  
  1933. * Use system features like Gestalt, the Process Manager, and the 
  1934. Notification Manager to get information about the system, and to 
  1935. communicate with the user.
  1936.  
  1937. * Try to patch as few traps as possible and use non-patching methods 
  1938. whenever possible (e.g., use a jGNEFilter instead of patching 
  1939. WaitNextEvent; the filter is more likely to remain compatible than 
  1940. your patch).  
  1941.  
  1942. * Don't use self-modifying code.  Self-modifying code changes the 
  1943. instructions from what they were compiled as, to something else, at 
  1944. run-time.  The classic example is to change the address in a JMP 
  1945. instruction at run-time so that it jumps to the address of the 
  1946. previous trap.  This may seem faster than using a global variable but 
  1947. it is only slightly faster.  It is harder to write, debug, and 
  1948. maintain self-modifying code, and it is definitely more likely to 
  1949. break with new system releases.  If you do use self-modifying code, 
  1950. remember to flush the cache.  See the tech note 'Cache As Cache Can' 
  1951. (#261) for more information on that subject.
  1952.  
  1953. * Use the Universal Headers for writing your extensions.  This will 
  1954. help to ease the transition when it comes.
  1955.  
  1956. --
  1957. [16] Any tips for INIT writing?
  1958.  
  1959. You may not want your INIT to actually do anything until after INIT 
  1960. time.  You can find the end of INIT time if you have a jGNEFilter 
  1961. installed when the first null event occurs.  The Notification Manager 
  1962. doesn't usually start processing requests until INIT time is over so 
  1963. posting a faceless notification request is another method to find the 
  1964. end of INIT time (probably the best if you don't need a jGNEFilter 
  1965. for something else).  You can also patch Launch to find the end of 
  1966. INIT time but this is trickier.
  1967.  
  1968. Unfortunately some extension writers do put up windows during INIT 
  1969. time.  Because of this it's possible that events will occur before 
  1970. INIT time is over.  To fail-safe the above approaches you also need 
  1971. to check for the presence of the Process Manager with a Gestalt call.  
  1972. The Process Manager isn't available until after INIT time.  If 
  1973. Gestalt reports that the Process Manager is not available then you 
  1974. need to reinstall your NM request, or simply wait for another event 
  1975. to be reported to your jGNEFilter when the Process Manager is 
  1976. available.
  1977.  
  1978. Here are some utility routines that can reduce the need for 68K 
  1979. assembler in your extensions:
  1980.  
  1981. pascal void SetA0( void* ) = { 0x205F };
  1982. pascal void SetA1( void* ) = { 0x225F };
  1983. void *   GetA0( void ) = { 0x2008 };
  1984. void *   GetA7( void ) = { 0x200F };
  1985.  
  1986.  
  1987. - -------------------------------------------------------------------
  1988.  
  1989. Trap Patches:
  1990.  
  1991. --
  1992. [17] What exactly is a trap patch?
  1993.  
  1994. A trap patch is a method for changing the functionality of a trap.  
  1995. The addresses of all the traps are maintained in the two trap 
  1996. dispatch tables.  By using the routine NSetTrapAddress and friends 
  1997. you can change the address of a particular trap to code that you 
  1998. provide.  When this is done at INIT time, all calls to the patched 
  1999. trap from all applications will go to your code, which in most cases 
  2000. will do something and then call through the existing trap in the 
  2001. ROMs.  Be warned that the Finder patches some traps when it starts up 
  2002. in a way that prevents previously-installed patches from executing.  
  2003.  
  2004. I recommend that you read the descriptions of the trap dispatch 
  2005. mechanism in the 'Using Assembly Language' chapters in IM I and IV 
  2006. and also in the 'Trap Manager' chapter in NIM Operating System 
  2007. Utilities.
  2008.  
  2009. Traps come in several types based on their parameter passing 
  2010. conventions.  Most toolbox traps use pascal calling conventions, 
  2011. which means that all parameters are passed on the stack and the 
  2012. return value, if any, is placed on the stack.  
  2013.  
  2014. Some traps use register-based calling conventions.  In these traps 
  2015. the parameters are passed in registers and the return value is 
  2016. returned in a register, usually D0.  For example all the Memory 
  2017. Manager traps are register-based and the File Manager traps are also 
  2018. register-based.  
  2019.  
  2020. Some traps are selector-based.  There are only so many spots in the 
  2021. trap-dispatch tables.  In order to preserve space in these tables 
  2022. selector-based traps have been developed.  In these traps a single 
  2023. trap serves as the front end for a number of system routines.  The 
  2024. parameters of these traps are passed in the usual manner, either on 
  2025. the stack or in registers, and a selector is also passed, usually in 
  2026. a register.  When the trap is called it checks the selector and then 
  2027. dispatches to the appropriate routine.  Patching each of these types 
  2028. of traps involves different mechanisms.  We'll look at samples of 
  2029. each one.
  2030.  
  2031. Patching traps on the PowerMac is a bit different than on the 68K 
  2032. Macs.  Most of the discussion here is aimed at patching traps on the 
  2033. 68K Macs.  Hopefully I'll learn some more about this subject soon and 
  2034. there will be some better info here on patching traps on the 
  2035. PowerMac.
  2036.  
  2037. --
  2038. [18] What's the difference between a head patch and a tail patch?
  2039.  
  2040. It is most common to add some functionality to a trap when patching 
  2041. it rather than just replacing the existing trap.  For instance I've 
  2042. written an extension that speaks the text in alerts by using the 
  2043. Speech Manager.  This works by patching Alert and friends.  When 
  2044. Alert is called the patch gets the text that appears in the alert and 
  2045. passes it to the Speech Manager.  The patch then calls the existing 
  2046. Alert trap that is in the ROMs.  A patch that works in this way is 
  2047. called a head patch; it does its business and then it calls the 
  2048. previous trap.
  2049.  
  2050. A tail patch is a bit different.  A virus-checking program might want 
  2051. to patch GetResource and then examine the resource that was read in 
  2052. to see if it contains a virus.  In order to do this the patch must 
  2053. first call the existing trap and then do its processing, and finally 
  2054. return to the application.  This is a tail patch because some 
  2055. processing occurs after the existing trap is called.  In order for a 
  2056. patch to be a head patch you must use a jmp instruction to jump to 
  2057. the previous trap.  If you use a jsr or a C function pointer to jump 
  2058. to the previous trap you have a tail patch.
  2059.  
  2060. The reason that this head and tail patch business has been so 
  2061. important in the past is because of an Apple invention called the 
  2062. come-from patch.  Patches were invented, of course, so that Apple 
  2063. could fix bugs in the ROMs and could update the routines in the ROMs 
  2064. with software.  This is why you can run system 7 on a Mac Plus, whose 
  2065. ROMs are obviously missing most of the additions made to the toolbox 
  2066. in recent years.  
  2067.  
  2068. Certain ROM routines are particularly large so it is inconvenient to 
  2069. patch them if they have bugs in them.  To get around this problem the 
  2070. Apple programmers searched for smaller routines that are called from 
  2071. the large buggy routines and placed patches in the smaller routines.  
  2072. These patches check the return address on the stack.  If it is the 
  2073. address of the buggy routine then a fix is applied.  If not then they 
  2074. just go on as usual.  The patches to these smaller routines are known 
  2075. as come-from patches.  If you tail patch one of these and then call 
  2076. the existing come-from patch, the return address on the stack will be 
  2077. in your patch and not the buggy routine that called you.  In this 
  2078. case the come-from patch will not apply its fix and your system will 
  2079. crash.  
  2080.  
  2081. The good news is that as of system 7 it is safe to apply tail 
  2082. patches.  The come-from patches still exist in system software, but 
  2083. NGetTrapAddress has been modified to return an address that is safe 
  2084. to use when applying tail-patches.  However, if you wish your 
  2085. extension to run in System 6 then tail-patches are not allowed.  This 
  2086. is documented in the Trap Manager chapter in NIM: OS Utilities.
  2087.  
  2088. If you absolutely positively need a tail patch in System 6 then the 
  2089. following logic may apply: (Just don't tell anyone that I told you 
  2090. this :-)  Apple is not releasing any new versions of System 6 so no 
  2091. new come-from patches will be forthcoming for System 6.  If you do 
  2092. careful testing of the traps you wish to tail-patch you will probably 
  2093. be OK.  In general traps not called from the ROMs, like Alert and 
  2094. MenuKey, will not contain come-from patches.
  2095.  
  2096. One final thing: In system 7 it is safe to apply tail-patches to all 
  2097. traps except FrontWindow.
  2098.  
  2099. --
  2100. [19] How do I patch a trap?
  2101.  
  2102. Here is some sample code for a head patch of Alert, a stack-based 
  2103. trap:
  2104.  
  2105. TrapPtr  gOldAlertTrapAddress;
  2106.  
  2107. /****InstallPatch***************************************************/
  2108.  
  2109. void 
  2110. InstallPatch (void)
  2111. {
  2112.    gOldAlertTrapAddress = GetToolTrapAddress( _Alert );
  2113.    SetToolTrapAddress( (long) AlertPatch, _Alert );
  2114. }
  2115.  
  2116. /****AlertPatch***************************************************/
  2117.  
  2118. pascal void 
  2119. AlertPatch( short alertID, ProcPtr filterProcPtr )
  2120. {
  2121.    SetUpA4();
  2122.  
  2123.    MyAlert( alertID) ;  //Do our thing
  2124.  
  2125.    //store the correct alert addr
  2126.    //in A0 while we can still access globals via A4
  2127.  
  2128.    asm   { move.l gOldAlertTrapAddress, A0 }
  2129.  
  2130.    RestoreA4();
  2131.    
  2132.    asm   {
  2133.          unlk     A6 //match the link generated by C
  2134.          jmp      (A0)  //jump to _Alert
  2135.       }
  2136. }
  2137.  
  2138. There are a number of details to note here.  This patch is of course 
  2139. part of a code resource that is loaded at INIT time and detached as 
  2140. described in an earlier section.  The routine InstallPatch must be 
  2141. called at INIT time.  
  2142.  
  2143. The routines GetToolTrapAddress and SetToolTrapAddress allow you to 
  2144. get and set the addresses of Tool Traps.  The similar routines 
  2145. GetOSTrapAddress and SetOSTrapAddress allow you to manipulate the 
  2146. addresses of OS traps.  The routines NGetTrapAddress and 
  2147. NSetTrapAddress allow you to manipulate the addresses of either, 
  2148. although they call glue code.  I recommend that you use the 
  2149. GetXTrapAddress and SetXTrapAddress calls.  There are two obsolete 
  2150. calls: GetTrapAddress and SetTrapAddress.  Don't use them.
  2151.  
  2152. The prototype for this patch is declared as 'pascal void' while the 
  2153. prototype for Alert is 'pascal short'.  Because this is a head patch 
  2154. it will not be returning a result; the result will be returned from 
  2155. the real Alert trap.  The pascal keyword is used to indicate pascal 
  2156. calling conventions.  It is not strictly required in all cases but 
  2157. does no harm.  
  2158.  
  2159. The Think C routines SetUpA4 and RestoreA4 are called to allow access 
  2160. to global variables by A4 addressing.  In this case 
  2161. gOldAlertTrapAddress is the only global variable we are addressing, 
  2162. unless any are used inside MyAlert.  Note that this variable is moved 
  2163. to A0 while access to global variables is still available.  In some 
  2164. cases one might move a global variable to a local variable, which 
  2165. doesn't rely on A4 addressing.  A4 could then be restored and the old 
  2166. trap address could be loaded into A0 later in the code. 
  2167.  
  2168. Because there is a parameter list the compiler generates a Link A6 
  2169. instruction at the start of this function.  In order to restore the 
  2170. stack a matching Unlk A6 must be placed at the end of the function.  
  2171. Since we are exiting by the jmp (A0) we must insert the Unlk A6 
  2172. ourselves.  The compiler does generate an Unlk A6 and an RTS at the 
  2173. end of this function, but they will never be executed.  The presence 
  2174. of the Link A6 instruction is dependent on the particular compiler 
  2175. you use and on its rules for generating a stack frame.  It is a good 
  2176. idea to disassemble the code for your trap patches to see whether a 
  2177. stack frame has been generated in order to determine if you need to 
  2178. insert the Unlk A6 instruction.  If you don't match the Link A6 with 
  2179. an Unlk A6 the stack will be screwed up.
  2180.  
  2181. It is essential that the stack look exactly the same on exit from a 
  2182. head patch as it does on entry.  If not you will surely crash.  (If 
  2183. you had good reason you could modify the value of a parameter on the 
  2184. stack, but that's another story.)  This patch saves and restores A4 
  2185. but does modify A0 and A1 (SetUpA4 uses A1).  In general, with head 
  2186. patches of stack-based traps you can modify A0, A1, D0, D1, and D2, 
  2187. but not any other registers.  You may need to look at the 
  2188. disassembled code to be sure that all your registers are properly 
  2189. saved and restored.  
  2190.  
  2191. The design of the patch as shown here, with the patch code calling a 
  2192. separate function to perform the actual functionality of the patch is 
  2193. a good design to follow with all but the simplest of patches.
  2194.  
  2195. You might think that you need to call StripAddress on the address of 
  2196. the patch routine before passing this address to SetToolTrapAddress.  
  2197. This is not necessary unless the address is actually a handle.  If 
  2198. you were to load a code resource and pass its entry point to 
  2199. SetToolTrapAddress then it would need to be stripped.
  2200.  
  2201. -- 
  2202. Brian  Stern  :-{)}
  2203. Toolbox commando and Menu bard
  2204. Jaeger@fquest.com
  2205.  
  2206. ---------------------------
  2207.  
  2208. >From Jaeger@fquest.com (Brian Stern)
  2209. Subject: INIT Writing FAQ [3-3]
  2210. Date: 28 Oct 1994 00:44:27 GMT
  2211. Organization: The University of Texas at Austin, Austin, Texas
  2212.  
  2213. --
  2214. [20] How do I patch a register-based trap?
  2215.  
  2216. Here is the code for a sample register-based trap patch:
  2217.  
  2218. TrapPtr     gMountVolAddress;
  2219.  
  2220. /****InstallPatch**************************************************/
  2221.  
  2222. void 
  2223. InstallPatch(void)
  2224. {
  2225.    gMountVolAddress =  GetOSTrapAddress( _MountVol );
  2226.    SetOSTrapAddress( (long) MountVolPatch, _MountVol );
  2227. }
  2228.  
  2229. /****MountVolPatch**************************************************
  2230.  
  2231. This is a register-based trap that has A0 set to point to its 
  2232. parameter
  2233. block on entry.  The  prototype for MountVol is:
  2234.  
  2235.    pascal OSErr PBMountVol( ParmBlkPtr paramBlock )
  2236.  
  2237. This patch beeps when a floppy or CD-ROM is inserted or when a 
  2238. harddrive is mounted by the Finder.
  2239.  
  2240. *******************************************************************/
  2241.  
  2242. pascal void 
  2243. MountVolPatch(void)
  2244. {
  2245. //Save some registers
  2246. //Save A0 since it's trashed by SetUpA4
  2247. //D1 contains the trap word
  2248.  
  2249.    asm   {  movem.l  a0/d0-d1, -(sp)      }
  2250.  
  2251.    SetUpA4();     //Allow access to global variables
  2252.  
  2253.    SysBeep( 5 );  //The guts of our head patch
  2254.    
  2255.    //store the correct MountVol addr
  2256.    //in A1 while we can still access globals via A4
  2257.    asm   {  move.l   gMountVolAddress, A1 }
  2258.  
  2259.    RestoreA4();   //Restore previous value in A4
  2260.    
  2261.    asm   {              //Restore the registers
  2262.          movem.l  (sp)+, a0/d0-d1
  2263.          jmp      (A1)     //jump to _MountVol
  2264.       }
  2265.  
  2266. }
  2267.  
  2268. This head patch is similar in structure to the patch to Alert with a 
  2269. few differences.  The prototype uses no parameters and has no return 
  2270. value. The single parameter is passed through A0.  This patch doesn't 
  2271. do anything with this value but it could be moved to a local variable 
  2272. and then used to reference the fields in the parameter block if 
  2273. desired.  Access to global variables is by the same A4 mechanism as 
  2274. in the Alert patch.  Note that _MountVol is an OS trap so 
  2275. GetOSTrapAddress and SetOSTrapAddress are used to set up the patch.  
  2276.  
  2277. Since A0 is used to pass the parameter to this trap we jump to the 
  2278. real _MountVol trap through A1.  
  2279.  
  2280. Obviously A0 must be saved and restored in this patch. OS traps 
  2281. expect to find the trap word in D1 so it must be saved and restored 
  2282. as well.  Three registers, A0, D0, and D1, are saved onto the stack 
  2283. with the movem instruction, and restored at the end of the patch.  
  2284.  
  2285. Think C doesn't generate a 'Link A6' at the start of this function 
  2286. because there are no parameters and no local variables.  Because of 
  2287. this no 'Unlk A6' is needed at the end of the function.
  2288.  
  2289. --
  2290. [21] Can you show me an example tail patch?
  2291.  
  2292. Here is another example of a patch to a register-based trap.  This 
  2293. sample is a tail patch and is dependent on the CodeWarrior 
  2294. environment.  Because CW allows you to specify that parameters are 
  2295. passed in registers this trap patch requires no assembly.
  2296.  
  2297. extern pascal OSErr (*Old_MountVol)( ParmBlkPtr pb : __A0 ) : __D0;
  2298.  
  2299. pascal OSErr My_MountVol( ParmBlkPtr pb : __A0 ) : __D0
  2300. {
  2301.    OSErr    err;
  2302.    long     saveA4 = SetCurrentA4();
  2303.  
  2304.    err = Old_MountVol( pb );
  2305.    DoSomthingFunc();
  2306.  
  2307.    SetA4( saveA4 );
  2308.    return err;
  2309. }
  2310.  
  2311. --
  2312. [22] How do I patch a selector-based trap?
  2313.  
  2314. Here is a sample patch to PrGlue.  This trap is the front end for all 
  2315. the Printing Manager routines.  Its selector is pushed on the stack
  2316.  
  2317. typedef struct 
  2318. {
  2319.    long     Selector;
  2320.    THPrint     hPrint;
  2321. } PrJobDialogStack;
  2322.  
  2323. TrapPtr     PrGlueAddress;
  2324.  
  2325. /****InstallPatch****************************************************
  2326. /
  2327.  
  2328. void 
  2329. InstallPatch(void)
  2330. {
  2331.    PrGlueAddress = GetToolTrapAddress( _PrGlue );
  2332.    SetToolTrapAddress( (long) PrGluePatch, _PrGlue );
  2333. }
  2334.  
  2335. /****PrGluePatch****************************************************
  2336.  
  2337. This is a stack-based trap with a long word selector also pushed 
  2338. onto the stack.  On entry the selector is at 4(A7).  The return 
  2339. address is at 0(A7).  After the 'Link A6' the selector is at 12(A7).
  2340.  
  2341. *******************************************************************/
  2342.  
  2343. #define kSelectorOffset 12
  2344. #define kPrJobDialogSelector 0x32040488
  2345.  
  2346. pascal void 
  2347. PrGluePatch(void)
  2348. {
  2349.    PrJobDialogStack  *StackPtr;
  2350.  
  2351.    //Get address of the stack frame
  2352.    //and save it in a local variable
  2353.  
  2354.    asm   { 
  2355.          lea    kSelectorOffset(A7), A0
  2356.          move.l A0, StackPtr
  2357.       }
  2358.  
  2359.    SetUpA4();     //Allow access to global variables
  2360.  
  2361.    //Check the selector
  2362.    if ( StackPtr->Selector == kPrJobDialogSelector )
  2363.    {
  2364.       SysBeep( 5 );
  2365.  
  2366.       //Pass hPrint to our function to do something
  2367.       DoSomethingFunc( StackPtr->hPrint );
  2368.    }
  2369.  
  2370.    //Store the correct PrGlue addr
  2371.    //in A0 while can still access globals via A4
  2372.    asm   { move.l PrGlueAddress, A0 }           
  2373.             
  2374.    RestoreA4();   //Restore previous value in A4
  2375.    
  2376.    asm   {
  2377.          unlk     A6 //match C's Link A6
  2378.          jmp      (A0)  //jump to _PrGlue
  2379.       }
  2380.  
  2381. }
  2382.  
  2383. In order to access the selector and the parameters for PrGlue we use 
  2384. a pointer to a struct.  Once the pointer is initialized correctly we 
  2385. can access the selector and any parameters from C easily.
  2386.  
  2387. According to NIM: PPC System Software it is not safe to patch 
  2388. selector-based traps with PPC native code.  All patches of selector-
  2389. based traps on the PowerMac should be written in 68K code.
  2390.  
  2391. --
  2392. [23] How do I patch a trap on the PPC?
  2393.  
  2394. See NIM 'PowerPC System Software' for a more complete discussion.  
  2395. There is also a new book by Tom Thomson called 'Power Macintosh 
  2396. Programming Starter Kit' that has examples of how to patch traps on 
  2397. the PowerMac.  
  2398.  
  2399. Patching traps on the PowerMac is similar to patching on the 68K 
  2400. architecture.  Of course you must generate a UniversalProcPtr for 
  2401. each of your patches in the system heap, and these are then passed to 
  2402. the SetXTrapAddress routines.  Since code fragments have their own 
  2403. globals the use of A4 or A5-based mechanisms for accessing global 
  2404. variables isn't needed.  In order to call the previous trap you need 
  2405. to call CallUniversalProc or CallOSTrapUniversalProc and return its 
  2406. result from your patch.  As a result all patches on the PowerMac are 
  2407. tail patches.
  2408.  
  2409. You may find an application called 'Traps Check' useful.  This app 
  2410. supplies a report about all the traps on a Powermac, indicating 
  2411. whether each trap is emulated or native.  Another way to do this is 
  2412. to drop into MacsBug and disassemble from the address of the trap 
  2413. you're interested in (e.g., 'il CopyBits' ).  For traps that are 
  2414. native you'll see a routine descriptor that begins with the 
  2415. MixedModeMagic trap (AAFE). This of course won't tell you if the trap 
  2416. has been patched.  You can identify a patch by whether it's in RAM or 
  2417. ROM, from its address.  Determining whether a patched trap is PPC 
  2418. native or not may take some additioinal sleuthing. You can find Traps 
  2419. Check at:  ftp://sumex-aim.stanford.edu/info-mac/dev/traps-check-
  2420. 10.hqx
  2421.  
  2422. Here is a sample PowerMac trap patch for GetResource:
  2423.  
  2424. UniversalProcPtr gGetResourceUPP;
  2425. UniversalProcPtr gGetResourcePatchUPP;
  2426.  
  2427. /****InstallPatch**************************************************/
  2428.  
  2429. void
  2430. InstallPatch(void)
  2431. {
  2432.    gGetResourceUPP = GetToolTrapAddress( _GetResource );
  2433.  
  2434.    gGetResourcePatchUPP = 
  2435.       NewRoutineDescriptor( (ProcPtr) GetResourcePatch,  
  2436.       kPascalStackBased, GetCurrentISA() );
  2437.  
  2438.    SetToolTrapAddress( gGetResourcePatchUPP, _GetResource );
  2439.  
  2440. }
  2441.  
  2442.  
  2443. /****GetResourcePatch*********************************************/
  2444.  
  2445. Handle 
  2446. GetResourcePatch( ResType theType, short theID )
  2447. {
  2448.    Handle   result;
  2449.  
  2450. //We don't need no 'DUMB' resources
  2451.    if ( theType == 'DUMB' )
  2452.       result = NULL;
  2453.    else
  2454.       result = (Handle) CallUniversalProc( gGetResourceUPP,
  2455.             kGetResourceProcInfo, theType, theID );
  2456.    
  2457.    return result;
  2458.  
  2459. }
  2460.  
  2461. --
  2462. [24] Can I write a fat trap?
  2463.  
  2464. //Under construction
  2465.  
  2466. --
  2467. [25] Tips?
  2468.  
  2469. If your patch isn't called you may have guessed wrong on whether it's 
  2470. a ToolTrap or an OSTrap.  The high bit of the second byte of the trap 
  2471. word is set for ToolTraps.  The following function can be used to get 
  2472. the correct trap address for both ToolTraps and OSTraps.
  2473.  
  2474. pascal void * GetCurrentTrapAddress( unsigned short trapWord )
  2475. {
  2476.    if ( trapWord & 0x0800 )
  2477.       return GetToolTrapAddress ( trapWord & 0x07FF );
  2478.    else
  2479.       return GetOSTrapAddress ( trapWord & 0x07FF );
  2480. }
  2481.  
  2482.  
  2483. If the machine crashes after leaving your patch you have probably 
  2484. munged the stack or not saved and restored all the registers that you 
  2485. must.
  2486.  
  2487. The Finder patches a number of traps when it loads in a way that 
  2488. prevents earlier trap patches from functioning.  If your patch 
  2489. doesn't appear to be called it may be one of these patches.
  2490.  
  2491. --
  2492. [26] What other sources of information are available?
  2493.  
  2494. Knaster 'How to Write Macintosh Software'
  2495. Knaster and Rollin, 'Macintosh Programming Secrets'.  These books on 
  2496. Mac programming has some excellent info on trap patching.
  2497.  
  2498. Tom Thomson 'Power Macintosh Programming Starter Kit' This book has 
  2499. some example code for writing trap patches and extensions on the 
  2500. PowerMac.
  2501.  
  2502. The Extension Shell package at:
  2503. ftp://sumex-aim.stanford.edu/info-mac/dev/src/extension-shell-13.hqx
  2504. Dair's email address has changed to: dair.grant@ucl.ac.uk.
  2505.  
  2506. Usenet Macintosh Programmers Guide
  2507. ftp://sumex-aim.stanford.edu/info-mac/dev/info/usenet-mac-prog-guide-
  2508. msw.hqx
  2509.  
  2510. All of the Apple Tech Notes have been made available on Apple's web 
  2511. server:   http://www.info.apple.com/dev/technotes/Main.html
  2512.  
  2513. -- 
  2514. Brian  Stern  :-{)}
  2515. Toolbox commando and Menu bard
  2516. Jaeger@fquest.com
  2517.  
  2518. ---------------------------
  2519.  
  2520. >From shawnl@andyne.on.ca (Dave Charlesworth)
  2521. Subject: Linking 68k object files to PPC program
  2522. Date: Thu, 27 Oct 1994 19:26:03 GMT
  2523. Organization: Andyne Computing
  2524.  
  2525. I want to link some third party code to a PowerPC program.  Can someone
  2526. point me to documentation on how to make this work?
  2527.  
  2528. I don't have source for the third party stuff.  I'm using MPW (ETO 15)
  2529. cross- platform tools (PPCLink, PPCC), and have the Inside Mac volume
  2530. "PowerPC System Software".  I haven't been able to find anything in it
  2531. or in the ETO documentation, but it must be somewhere!
  2532.  
  2533. Thanks.
  2534.  
  2535. Shawn Leclaire
  2536.  
  2537. +++++++++++++++++++++++++++
  2538.  
  2539. >From zellers@pokey.basilsoft.com (Steve Zellers)
  2540. Date: Fri, 28 Oct 1994 20:52:49 -0800
  2541. Organization: BasilSoft, Inc.
  2542.  
  2543. In article <CyCJBF.Ms4@andyne.on.ca>, shawnl@andyne.on.ca (Dave
  2544. Charlesworth) wrote:
  2545.  
  2546. > I want to link some third party code to a PowerPC program.  Can someone
  2547. > point me to documentation on how to make this work?
  2548.  
  2549. Assuming you mean that the third party code is 68k, you can't.  You'll
  2550. have to write a stub code resource that re-exports all the symbols you
  2551. need through a paramblock as some sort using route descriptors.
  2552.  
  2553. --smz
  2554.  
  2555. +++++++++++++++++++++++++++
  2556.  
  2557. >From wdh@fresh.com (Bill Hofmann)
  2558. Date: Sat, 29 Oct 1994 18:27:36 GMT
  2559. Organization: Fresh Software
  2560.  
  2561. In article <CyCJBF.Ms4@andyne.on.ca>, shawnl@andyne.on.ca (Dave
  2562. Charlesworth) wrote:
  2563.  
  2564. > I want to link some third party code to a PowerPC program.  Can someone
  2565. > point me to documentation on how to make this work?
  2566. > I don't have source for the third party stuff.  I'm using MPW (ETO 15)
  2567. > cross- platform tools (PPCLink, PPCC), and have the Inside Mac volume
  2568. > "PowerPC System Software".  I haven't been able to find anything in it
  2569. > or in the ETO documentation, but it must be somewhere!
  2570. Nope, not really.  Maybe some of the MacTech articles have mentioned it.
  2571. But what you have to do is:
  2572.     * find out which routines *you* call in the library
  2573.     * write some 68k code that wraps the library in a way that you can
  2574.       call it: either use a selector-based approach (ie, if message==1,
  2575.       call function 1, etc) or make a routine that returns a table of 
  2576.       procptrs
  2577.     * compile/link the wrapper with the library
  2578.     * create proc infos and stub code to call your 68k wrapper in your
  2579.       PowerPC program
  2580.     * debug :->
  2581.  
  2582. Or, yell at the third party until they produce a PowerPC version (shared
  2583. library, or whatever).
  2584.  
  2585. -Bill
  2586.  
  2587. -- 
  2588. Bill Hofmann                                  wdh@fresh.com
  2589. Fresh Software and Instructional Design       voice: +1 510 524 0852
  2590. 1640 San Pablo Ave #C, Berkeley CA 94702 USA  fax:   +1 510 524 0853
  2591.  
  2592. ---------------------------
  2593.  
  2594. >From rjkmehta@bu.edu (Ravi Mehta)
  2595. Subject: Network Programming
  2596. Date: 19 Oct 1994 16:20:21 GMT
  2597. Organization: Boston University
  2598.  
  2599. I want to write some networkable software, but am completely new to network
  2600. programming.  Besdies IM: Networking ( which I will pickup ) is there
  2601. anything else that would help?  Will IM: Networking discuss programming
  2602. for BOTH AppleTalk and Ethernet?  If not, what would be a good
  2603. source for learning how to write Ethernet and AppleTalk compatible software.
  2604.  
  2605. Thanks in advance.
  2606.  
  2607. Ravi J. K. Mehta
  2608. Terminal Sunset Software
  2609.  
  2610.  
  2611. +++++++++++++++++++++++++++
  2612.  
  2613. >From andym96@aol.com (AndyM96)
  2614. Date: 20 Oct 1994 01:13:05 -0400
  2615. Organization: America Online, Inc. (1-800-827-6364)
  2616.  
  2617. In article <383h05$a37@news.bu.edu>, rjkmehta@bu.edu (Ravi Mehta) writes:
  2618.  
  2619. <<
  2620. Will IM: Networking discuss programming
  2621. for BOTH AppleTalk and Ethernet?  If not, what would be a good
  2622. source for learning how to write Ethernet and AppleTalk compatible
  2623. software.>>
  2624. yes, IM networking  discusses how to do that. Also, a good book is
  2625. "Programming with AppleTalk" by Michael Peirce -code samples are in
  2626. Pascal, though, but it is a thorough and detailed description of how
  2627. AppleTalk protocols work & how to use 'em. 
  2628. BTW, if you dicover a code sample how to write a requester-responder pair
  2629. using ATP  in C, <<PLEASE>> e-mail me  @ andym96@aol.com -I've been trying
  2630. to get this info for a couple of weeks now with no avail.
  2631. Andy
  2632.  
  2633. +++++++++++++++++++++++++++
  2634.  
  2635. >From ntuck@muddcs.cs.hmc.edu (Nathan D. Tuck)
  2636. Date: 20 Oct 1994 20:02:38 GMT
  2637. Organization: Harvey Mudd College, Claremont CA
  2638.  
  2639.  
  2640. >In article <383h05$a37@news.bu.edu>, rjkmehta@bu.edu (Ravi Mehta) writes:
  2641. >
  2642.  
  2643. >Will IM: Networking discuss programming
  2644. >for BOTH AppleTalk and Ethernet?  If not, what would be a good
  2645. >source for learning how to write Ethernet and AppleTalk compatible
  2646. >software.>>
  2647.  
  2648. For both AppleTalk and Ethernet?  AppleTalk is a software protocol while
  2649. Ethernet is the physical format that AppleTalk runs over.  If you mean
  2650. LocalTalk and Ethernet, the two should be equivalent so far as ATP
  2651. API's are concerned.  If you mean to run transparantly over different
  2652. protocol stacks such as ATP and IPX/SPX or TCP/IP, that is another
  2653. question entirely.
  2654.  
  2655. Nate
  2656. ntuck@hmc.edu
  2657.  
  2658.  
  2659.  
  2660. +++++++++++++++++++++++++++
  2661.  
  2662. >From Yorick_Ph*nix,MacTel_Iconex@metro.mactel.org (Yorick Ph*nix,MacTel_Iconex)
  2663. Date: 29 Oct 1994 02:48:38 GMT
  2664. Organization: MacTel Metro BBS, London, England.
  2665.  
  2666. Ravi
  2667.  
  2668. > I want to write some networkable software, but am completely new to
  2669. > network programming.  Besdies IM: Networking ( which I will pickup )
  2670. > is there anything else that would help?
  2671.  
  2672. There is a very good book called something like Introduction to AppleTalk
  2673. Programming - I have a copy at the office and I learnt all my Network
  2674. Programming from it. It is possibly published by Addison-Wesley and is one in
  2675. a series where Scott Knaster is the Series Editor.
  2676.  
  2677. AppleTalk programming is what you should be doing (ATP, NBP, ADSP, PAP, etc)
  2678. whereas LocalTalk and EtherNet are the phsyical mediums over which the
  2679. network data travels - you shouldnt need to get involved at this level or
  2680. even know which phsyical medium your program is dealing with.
  2681.  
  2682. Yorick
  2683.  
  2684. - sent via an evaluation copy of BulkRate (unregistered).
  2685.  
  2686. --
  2687. ****************************************************************************
  2688.               MacTel Metro - Europes largest Mac specific BBS
  2689.   The views expressed in this posting those of the individual author only.
  2690.                     Send mail to this user at either :-
  2691. INTERNET:User_Name@metro.mactel.org          [use underline]  between first
  2692.  FIDONET:User.Name@f202.n254.z2.fidonet.org  [use fullstop ]  & last names
  2693. ****************************************************************************
  2694.  
  2695. ---------------------------
  2696.  
  2697. >From walkerj@math.scarolina.edu (James W. Walker)
  2698. Subject: Stuck in SyncWait again
  2699. Date: Sat, 15 Oct 1994 21:39:18 -0500
  2700. Organization: Dept. of Mathematics, Univ. of South Carolina
  2701.  
  2702. When an application freezes, dropping into MacsBug often reveals that it
  2703. is stuck in SyncWait.  When that happens, typing es to MacsBug or using
  2704. force-quit does nothing.  Is there any hope for someone with debugger
  2705. skills slightly below those of "Kon & Bal" to get the app out of SyncWait
  2706. and make it die a clean death, or should I just restart the Mac?
  2707. -- 
  2708.  Jim Walker
  2709.  
  2710. +++++++++++++++++++++++++++
  2711.  
  2712. >From jonasw@lysator.liu.se (Jonas Wallden)
  2713. Date: 16 Oct 1994 09:57:15 GMT
  2714. Organization: (none)
  2715.  
  2716. walkerj@math.scarolina.edu (James W. Walker) writes:
  2717.  
  2718. >When an application freezes, dropping into MacsBug often reveals that it
  2719. >is stuck in SyncWait.  When that happens, typing es to MacsBug or using
  2720. >force-quit does nothing.  Is there any hope for someone with debugger
  2721. >skills slightly below those of "Kon & Bal" to get the app out of SyncWait
  2722. >and make it die a clean death, or should I just restart the Mac?
  2723. >-- 
  2724. > Jim Walker
  2725.  
  2726. The SyncWait loop waits for a parameter block error code to drop below +1
  2727. (which is the value used while the call is in progress), and as we all know
  2728. this error code is 0 (noErr) for a successful request and negative for errors.
  2729.  
  2730. So, look at the SyncWait code to see which word it tests (usually something
  2731. like 10(A0)) and set this word to an error code (e.g. FFD5 for fileNotFound)
  2732. and it will often get you out of the lock.
  2733.  
  2734. I've used it successfully in Mosaic several times where it seems to hang
  2735. when I abort a connection, and at other times when the computer won't
  2736. reboot after a crash.
  2737.  
  2738. BTW, I have a MacsBug dcmd which lists error strings from error codes.
  2739. This is great as it's rather difficult to use ObiWan at these times...
  2740. Can't remember if I got it from sumex or a Developer CD, though.
  2741.  
  2742. --
  2743. `.`.   Jonas Wallden                    `.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.
  2744. `.`.`.   Internet: jonasw@lysator.liu.se  `.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.
  2745. `.`.`.`.   AppleLink: sw1369                `.`.`.`.`.`.`.`.`.`.`.`.`.`.`.
  2746.  
  2747. +++++++++++++++++++++++++++
  2748.  
  2749. >From wysocki@netcom.com (Chris Wysocki)
  2750. Date: Sun, 16 Oct 1994 16:31:58 GMT
  2751. Organization: NETCOM On-line Communication Services (408 261-4700 guest)
  2752.  
  2753. In article <walkerj-1510942139180001@192.0.2.1>,
  2754. James W. Walker <walkerj@math.scarolina.edu> wrote:
  2755.  
  2756. >When an application freezes, dropping into MacsBug often reveals that it
  2757. >is stuck in SyncWait.  When that happens, typing es to MacsBug or using
  2758. >force-quit does nothing.  Is there any hope for someone with debugger
  2759. >skills slightly below those of "Kon & Bal" to get the app out of SyncWait
  2760. >and make it die a clean death, or should I just restart the Mac?
  2761.  
  2762. Here's a MacsBug dcmd that I wrote a few weeks ago that simply does a
  2763. KillIO for a specified driver.  You might be able to use this when
  2764. you're stuck in _SyncWait to kill the pending request and get out
  2765. safely.  Since it's so small, I've attached it below, along with the
  2766. source code to it; hope you find it useful.
  2767.  
  2768. Chris.
  2769.  
  2770. - ------
  2771. (This file must be converted with BinHex 4.0)
  2772. :$dYTE'a*6b"NBfeN,R0TG!"6594%8dP8)3#3"!`[!*!%r2T6593K!!-!!!`[FNa
  2773. KG3,r!*!$&[rr$3d)5fPXE%P2,Q1Gm9!"8)H!!"8BQJ#3!i!!N!3"@**J4()!N"3
  2774. %R!#3"2q3"&4&@&408&-J!3#UUh$bUUYlc3!!!D`!!!F8!!!"%3!!!`8KNZFl!*!
  2775. 'P&84!!JFl(B)BP9k**AKrPcJ1V9Vp)Y)6-*K36-cDDB[,XlVjq(F(52TkHdlqe,
  2776. 528kFPY3cj!m%XHl!BBHmiNQm1dk-[J53!+ZSdrTSIqk,mhTa[FiTXQ&$R%R#AZp
  2777. J%C'5-PeA5k21&&hTI(#%T@*rS!G1i4NCK)8cm@"R"EPI9L3pM+@6dTk5%FD1N3A
  2778. d$XA1E2eFqc+pj4*T[kc89#T`30$qQH9`rdJka4&Q8TZ(CNTR%"@FBEY*#SIZ2"h
  2779. 9fMXDeZAACHmJpa[Df"Z%R"!,95(&3f,U3"Z(Ym@d21(%V@i%L*f5MGaVHQmS26m
  2780. &RBReV@XMPA-rAE+RSe"S$Z"F6FJ*%'1Q+$8VMjpUY##U5Kq`#Ni"b1-*-S$*bXK
  2781. 4JLr#EMe#Ml!M[ailMaacd#PK!b98pT)")`1!&5$A8l)#j$1!VjF`XK,d-B*q"!"
  2782. hAB-N6-+1(#0--Q$N'%%6)`a2$JrX`!#kK`Pj*56[%r*'5$QilV!N)HGDH5U8kcF
  2783. Lb&L4`84EH%HC1bZRk(&VKIGF`EMUNr2F#JHhPG0X*U+rUDbBjVj2[X&4VrF8SS2
  2784. A*ZF@EMTVU`kmP"+LN`2,(EGcRR9#J*bU+BHVi'NV5![Y2"S`VMa-K(@qh8FA!Lq
  2785. 16JRdZXI2ZVfRK0N&)HH@8mqa,+X,q+4Pk21`Qb52K'+bc$Lmq&!ClMVjk8jb`HH
  2786. #hBX#&YmPPpCU'c9E85Z`dFPE1i8TI4!NhHl*2`FqM)4`&399fDAbY[Sh3F6%8-H
  2787. SK,N@'Gb&6826Ca,"234$,5f'hVD6V`NjdeTbUN$2i!3Q9$Vq2#&5UbNL1m(6-*K
  2788. &ia[1`)a4FMe#PS"Eqa`jGJ[K@3lT1Y568mZrP"`T6`J!"L5-1Kj(D+#%lk1!M*(
  2789. c@6$IDUqi0&%EMKH@,Yi+aG2@Cp1-'*DKbU,9a[Jr2!"Ji"b'"JU0(d)J`@[`1HD
  2790. cBSl6K8APm6l&XrUED,q,m!51Rm')'amRXA(pfH1&(Y3GKq0S3FfYYM*c+4S'94V
  2791. !E%HRepbrjdYrZ63iRNjSP4jJ*BrK3-mD-c'"&)rK&$JLa)`l3NFJmIq'6pkA"8+
  2792. EZPaEhfjia3r*40R`V%CK9#Q@(TKaA4Q*2m25$dIHl[K#9"T-QQk$amFV[X6qXK5
  2793. MhGQ(BQ,)%e!DYb"@Y%m&VQ3ibQj5bR8HMY-5$h@AHcI,I@N9,MqQ`SI+fR,I`ET
  2794. QY'Mi)*[a#CTDdB5VJ@6i&,*DBN-4bI[8k9EIhN6H8,h,-DEC4pbZKaaErCmFC6!
  2795. TM+mHNY`jr-QLY,mfA$dNfHTrjeM&he@0%RV(lDZYSR3$l2diiU*iZUaC$GPqcGe
  2796. q(c-qSD@XPh&A8kPQ5Lr#&XFR`aVmJ2d&CcrI&'[jVUYeT3#VC*Am"`!0$3Y,D@a
  2797. X58mZE@&VC3&3Ki!!&4LD!*!$J!#3"!&BNQ!-d`#3%4B!!!H+!*!%rj!%9%9B9%e
  2798. 38b!"!+UVH01UUhSa!!!"V!!!!NN!!!%K!!!"AA@DY)S!N!B0#"%!#"cXGJKLe6K
  2799. CXcV%MX[FG-ra@EM-Q*1JqQRRHDD'!FE8USiQY*ZBYf-N2EepCem''8Jp6U#@e$2
  2800. N$`3a!Z8mCMMKX0iG*`kj(F$6hQPp0(R#e8GeIJ%+eS4fkG!QqH5mj@Eb5J'&SF-
  2801. f2IHXLC)Rh(G9"qMC168fkZRVLD,5%1MFep-UPejSIKqSAS9"2M5KC&YdF44UJT2
  2802. VUSRD-6A0`HGUqL"IcAc*%fEiUN1YTKkBb+#`dhG'kSD9Um1'9DY$D@F3&EaqcNJ
  2803. +Krk4G&5rae5"XdH@`bNCiEMbFH@pN!!6BL%!f*2KHAX@[q2%BI(1MNACD0i4kc1
  2804. HBUp[A4ZT0(jFbCk13U%jJ(-e)5G!M*NbjfliU8B,SLT[(QS"!*!$8E@%YC*-rU"
  2805. 2Qj68cKm-QZh*@Hk!6mM($"M#ERmSV%fbNSK()*!!!4()aB$ANqA0`C`L2mDq%%M
  2806. 2eLET'H32JdlCBHJ*q'-5`fcNcf5`0QNL509S'S!F4J*CaSH!-cN1di%Z'!3j*!k
  2807. 3!#rX3a'I0cPASHm1CIT!'jiDC`0a&JaMJV"p)3`br#L-*GSF$MkJ85JE+M30NM`
  2808. SQT5N4cihpZ@fe)A!!(N1%qB@U#40R4U[h%k'X9TPqiV&(`U!HPUqBl$idj%EqAh
  2809. KR22p)1G,GLI$HN"V6qrMmq#`GSR%%q53!-0mm$B3$8L%TL)R&m,q,"m"PZ,L,+N
  2810. 9j`pk$6`qA9K&U@`S6$*k'1,PKca"cZX$SYaXS8Np-"!iIIf"h-dl&!DNCBHa,mX
  2811. %JeiI'Q6`TA1CQ@4IEH6,#)[LP9-6bZ,5VbShJ"`"H6U3!2[M,6C$f)Fbh"j5iqd
  2812. ib`DmlV2UfAi0!!C,D@aX58pH3*ha8!&3Ki!!&4LD!*!$J!#3"!&BNQ#bS3#3%!5
  2813. F!*!)rj!%FR0bBe*6483"!+UVGE5UUh[D!!!(@`#3"J3e!*!%6D`!N!Mf(#0%$L)
  2814. UV5%U359,L)ir2,PP8%TR&'k`ZDaG08a*8EM1j[X@-!H9V*B9TEeVY40LeBBHkik
  2815. d""f8``-#qHkTril9mECq)[ZJMDJqD&Y$,kRKF%G[EjmqVDQJ'YKb9*Epd-r)f80
  2816. lCrk#pNeprZ(hI,RIi`m5d[MlTja#6SFVp"EjQhp'Xk8C8Sh%T#R5bG+*dQ6T1'Q
  2817. L0&kUNXC*&9+j9#D95#l*'GV%TJEHbMfhqq+AGV%0+kLqM+A*&6S3@TZlTqd94eQ
  2818. Y5Q9qAqi6$AAN5K)GLM3PCk$b286IDY[X1"ak1(F6qXI4hi2qE[3V`$dSH"1[E&0
  2819. cpk*q#fMG+VM)li+(9F[9h(fja`1[jHjRlAY+cL$SQN-21e2e[YbpSBH,DPDY$(F
  2820. P+X!+!LYhI9I2@Q!%@%C$DG[qHS'd0C5kQR)r$(FP'clFP'4)a(K@8m,AYTNH"cX
  2821. )QL(!`!dl(PJ!-%L',3'Q"9BGHYMae[SZG0NpCF$c3`mI4Q*YVrDF#$3H[0G&hU*
  2822. AEM,`X("AafY9`lRE3ZIiEJeP,`YdGABfKi)YS@Mh@H3SUFUUIDSfS$+GEmTb`f4
  2823. 8%4P56@Q3!(&Geh6bXPT9-lXbA'h4p9P%PD`fUmTQ5cTM$YN-8#L5iQX%5FCRD+U
  2824. TDiU0'f'Y*UZV2'jE%XM$M'`XaJdMN9@)UZeG*TJDLqYb2hBFSDQ-X8"+P`ffEXM
  2825. 3BRdbGQ$F3KEK'C-e,PQbJ1Kd+)`e$%3Q5#c[B!Ef'0US5I'#PIQbQE,`QB!aj&)
  2826. eQdC'NU+-CkmPUUpSreQ1@!HVk"kZD@*c$arDij[mbF1jqSV3`fpR-M5RkI#K@M9
  2827. h+(41+$ZQ"cUjRcamk)6lb%0dK&r&a!cD[PA!,Dm8P3R&5"p9q(`B#pK2U,lr-VK
  2828. 9l[&p(bi+A&"ml[0!+YjSQ([iX"p*`r3fjRijkN,FE)YTbX3-e90pD8e&prCk"h6
  2829. A@A2H2+TN%&k0m+TM2LTc$Q20'YU'frE2*S'IfP9,bFQX*$*F6ka8G0(#rHkZRe0
  2830. &6fhNSP8lY3V"@cGXT4,eL*9+3AQQ3H6DGRKp9f5RqRUQr2i,Be@X@'miX0hLRF5
  2831. QdJ0rIVH0(eU2r8-1jJk1c!@N9ZfUGjLd`%IPp8jibcf5@35bSCNTp2,3`h505#b
  2832. FmQK4(5@VmQNTSE`hh08cHFe1N9$ECIEF9%fhI%pIhm9F)kRNr,X8SZ%8203,6NJ
  2833. pZ6#`kZDhU(cH&R+'$PjpZ+HNSjNFd0Y*-aMk$c683Z2CTP"fKD1YH99ciZ3DR$#
  2834. @jQ6jqGpZDfjVDR#d03fr-)rm6@h3X$5IFAjpd3)keD%l"!0ZKC3'Tdipach6c-F
  2835. rkrrkm2dAm&rZ[Z#CjV*(LH+[R6Te`G43pMrG6jj3AXH&c-`qqm@6,J0LSRQBP"R
  2836. T1$#YkiQm9X6CHr)hmP8!N!2-eJ!!:
  2837.  
  2838. +++++++++++++++++++++++++++
  2839.  
  2840. >From h+@nada.kth.se (Jon W{tte)
  2841. Date: Sun, 16 Oct 1994 20:15:31 +0100
  2842. Organization: Royal Institute of Something or other
  2843.  
  2844. In article <walkerj-1510942139180001@192.0.2.1>,
  2845. walkerj@math.scarolina.edu (James W. Walker) wrote:
  2846.  
  2847. >When an application freezes, dropping into MacsBug often reveals that it
  2848. >is stuck in SyncWait.  When that happens, typing es to MacsBug or using
  2849. >force-quit does nothing.  Is there any hope for someone with debugger
  2850. >skills slightly below those of "Kon & Bal" to get the app out of SyncWait
  2851. >and make it die a clean death, or should I just restart the Mac?
  2852.  
  2853. Usually this means a SCSI request isn't being served (or an 
  2854. Ethernet request, or a Serial Port request, or...) This is 
  2855. usually caused because of buggy drivers (like early Applied 
  2856. Engineering drivers, some CD-ROM and MO drivers and version 1.x 
  2857. of the Digidesign card drivers)
  2858.  
  2859. When something hangs in _vSyncWait, it waits for the word at 
  2860. (a0)+10 to go 0 or negative (this is ioResult in the parameter 
  2861. block) One thing you can TRY is:
  2862.  
  2863.     atba
  2864.     sw a0+10 ffff
  2865.     g
  2866.     atc
  2867.     es
  2868.  
  2869. This will make the app halt as soon as it gets to an A-trap (so 
  2870. it won't just get stuck again) Then it fakes an interrupt 
  2871. service routine that sets the result to -1 (an error code) Run 
  2872. with this; and as soon as an A-trap is hit, clear breaks and 
  2873. exit.
  2874.  
  2875. However, since this is a driver that got hosed, chances are 
  2876. you'll run into the same problem an instant later, so it's 
  2877. usually not terribly helpful.
  2878.  
  2879. There are also several conditions which can make this fail:
  2880.  
  2881. - If some idiot masked interrupts, that's the reason you're
  2882.   waiting for an interrupt that's never serviced. Check with TD
  2883.   and look at the Int= figure - should be 0. 7 is real bad.
  2884.  
  2885. - If this was because of a file manager request; the file 
  2886.   manager is now in a meeting for the rest of the day, which 
  2887.   means you earned just about nothing by breaking out.
  2888.  
  2889. - If the driver makes interesting assumptions about the return 
  2890.   value you use (ffff==-1 in this case) OR wants a completion 
  2891.   routine to be called, you're probably hosed anyway.
  2892.  
  2893. There should be a law only competent people can write drivers. 
  2894. Unfortunately it seems to be the other way around with some 
  2895. people "Hey, we've got this interesting hardware we can sell. 
  2896. However, hiring someone expensive to write the drivers would 
  2897. eat into our margin way too much. Isn't Joes 13-year-old kid
  2898. into computers? Have him whip something up and we'll give him a 
  2899. Happy Meal."
  2900.  
  2901. Hardware without drivers is pretty useless.
  2902.  
  2903. Cheers,
  2904.  
  2905.                     / h+
  2906.  
  2907.  
  2908. --
  2909.   Jon Wätte (h+@nada.kth.se), Hagagatan 1, 113 48 Stockholm, Sweden
  2910.  
  2911.  -- I don't fear death, it's dying that scares me.
  2912.  
  2913.  
  2914. +++++++++++++++++++++++++++
  2915.  
  2916. >From jumplong@aol.com (Jump Long)
  2917. Date: 17 Oct 1994 00:44:01 -0400
  2918. Organization: America Online, Inc. (1-800-827-6364)
  2919.  
  2920. In article <walkerj-1510942139180001@192.0.2.1>,
  2921. walkerj@math.scarolina.edu (James W. Walker) wrote:
  2922.  
  2923. >When an application freezes, dropping into MacsBug often reveals that it
  2924. >is stuck in SyncWait.  When that happens, typing es to MacsBug or using
  2925. >force-quit does nothing.  Is there any hope for someone with debugger
  2926. >skills slightly below those of "Kon & Bal" to get the app out of SyncWait
  2927. >and make it die a clean death, or should I just restart the Mac?
  2928.  
  2929. Here are a couple of paragraphs from the article "Asynchronous Routines on
  2930. the Macintosh" in develop issue #13 that explain deadlock conditions and
  2931. SyncWait:
  2932.  
  2933. - ----
  2934.  
  2935. Avoid SyncWait.
  2936.  
  2937. Does your Macintosh just sit there not responding to user events? Drop
  2938. into the debugger and take a look at the code that's executing. Does it
  2939. look like this?
  2940.  
  2941. MOVE.W $0010(A0),D0
  2942. BGT.S  -$04,(PC)
  2943.  
  2944. That's SyncWait, the routine that synchronous calls sit in while waiting
  2945. for a request to complete. Register A0 points to the parameter block used
  2946. to make the call, offset $10 is the ioResult field of the parameter block,
  2947. and SyncWait is waiting for ioResult to be less than or equal to 0
  2948. (noErr).
  2949.  
  2950. The ioResult field is changed by code executing as a result of an
  2951. interrupt. If interrupts are disabled (because the synchronous call was
  2952. made at interrupt time) or if the synchronous call was made to a service
  2953. that's busy, you'll be in SyncWait forever. Take a look at the parameter
  2954. block and where it is in memory, and you'll probably be able to figure out
  2955. which synchronous call was made at interrupt time and which program made
  2956. it.
  2957.  
  2958. - ---
  2959.  
  2960. Deadlock is a state in which each of two or more processes is waiting for
  2961. one of the other processes to release some resource necessary for its
  2962. completion. The resource may be a file, a global variable, or even the
  2963. CPU. The process could, for example, be an application's main event loop
  2964. or a Time Manager task.
  2965.  
  2966. When deadlock occurs on the Macintosh, usually at least one of the
  2967. processes is executing as the result of an interrupt. VBL tasks, Time
  2968. Manager tasks, Deferred Task Manager tasks, completion routines, and
  2969. interrupt handlers can all interrupt an application's main thread of
  2970. execution. When the interrupted process is using a resource that the
  2971. interrupting process needs, the processes are deadlocked.
  2972.  
  2973. For example, suppose a Time Manager task periodically writes data to a
  2974. file by making a synchronous Write request, and an application reads the
  2975. data from its main event loop. Depending on the frequency of the task and
  2976. the activity level of the File Manager, the Time Manager task may often
  2977. write successfully. Inevitably, however, the Time Manager task will
  2978. interrupt the application's Read request and deadlock will occur.
  2979.  
  2980. Because the File Manager processes only one request at a time, any
  2981. subsequent requests must wait for the current request to complete. In this
  2982. case, the synchronous request made by the Time Manager task must wait for
  2983. the application's Read request to complete before its Write request will
  2984. be processed. Unfortunately, the File Manager must wait for the Time
  2985. Manager task to complete before it can resume execution. Each process is
  2986. now waiting for the other to complete, and they will continue to wait
  2987. forever.
  2988.  
  2989. Synchronous requests at interrupt time tend to produce deadlock, because
  2990. the call is queued for processing and then the CPU sits and spins, waiting
  2991. for an interrupt to occur, which signals that the request has been
  2992. completed. If interrupts are turned off, or if a previous pending request
  2993. can't finish because it's waiting to resume execution after the interrupt,
  2994. the CPU will wait patiently (and eternally) for the request to finish -
  2995. until you yank the power cord from the wall.
  2996.  
  2997. - ---
  2998.  
  2999. Read the rest of that article, it'll help you write code that doesn't end
  3000. up in SyncWait.
  3001.  
  3002. - Jim Luther
  3003.  
  3004.  
  3005. +++++++++++++++++++++++++++
  3006.  
  3007. >From walkerj@math.scarolina.edu (James W. Walker)
  3008. Date: Mon, 17 Oct 1994 23:41:46 -0500
  3009. Organization: Dept. of Mathematics, Univ. of South Carolina
  3010.  
  3011. In article <37sveh$t0t@newsbf01.news.aol.com>, jumplong@aol.com (Jump
  3012. Long) wrote:
  3013.  
  3014. > Read the rest of that article, it'll help you write code that doesn't end
  3015. > up in SyncWait.
  3016.  
  3017. I guess I didn't make it clear in my original post, but it's not *my* code
  3018. that gets stuck in SyncWait. It's usually Internet apps like Anarchie.  I
  3019. was just wondering whether there was anything I could do when it happens,
  3020. other than restart, and this thread has given me some ideas.  Gee, I can
  3021. hardly wait for the next freeze. :-)
  3022. -- 
  3023.  Jim Walker
  3024.  
  3025. +++++++++++++++++++++++++++
  3026.  
  3027. >From bierman@caelab1.cae.wisc.edu (Peter Bierman)
  3028. Date: Tue, 18 Oct 1994 14:36:31 -0600
  3029. Organization: Happy Frogs, Inc.
  3030.  
  3031. In article <walkerj-1710942341460001@192.0.2.1>,
  3032. walkerj@math.scarolina.edu (James W. Walker) wrote:
  3033.  
  3034. > In article <37sveh$t0t@newsbf01.news.aol.com>, jumplong@aol.com (Jump
  3035. > Long) wrote:
  3036. > > Read the rest of that article, it'll help you write code that doesn't end
  3037. > > up in SyncWait.
  3038. > I guess I didn't make it clear in my original post, but it's not *my* code
  3039. > that gets stuck in SyncWait. It's usually Internet apps like Anarchie.  I
  3040. > was just wondering whether there was anything I could do when it happens,
  3041. > other than restart, and this thread has given me some ideas.  Gee, I can
  3042. > hardly wait for the next freeze. :-)
  3043.  
  3044.  
  3045. Well, all of the ideas are good and accurate, but here's an easy fix.
  3046.  
  3047. Do a step (oa-T) till Macsbug says "Will [not] branch". Then type:
  3048.  
  3049. pc=pc+2
  3050.  
  3051. g
  3052.  
  3053. That will jump you out of the loop. It's faster than "fixing" the loop
  3054. condition. Just note that what John said is true: it'll probobly happen
  3055. again withing a short time. Restart right away.
  3056.  
  3057. -Peter
  3058.  
  3059. -- 
  3060.        Peter Bierman       \  The Metropolis  \ The most primitive part of the
  3061. bierman@caelab1.cae.wisc.edu\  (614)-846-1911  \   the brain concerns itself
  3062.                              \  600MB Mac Files \     with the "Four F's":
  3063. "I've changed my mind, Hobbes.\  FirstClass GUI  \ Feeding, Fighting, Fleeing,
  3064.  people are scum." --Calvin    \  Info-Mac CD-ROM \     and Reproduction.
  3065.  
  3066. +++++++++++++++++++++++++++
  3067.  
  3068. >From richardb@cocytus.demon.co.uk (Richard Buckle)
  3069. Date: Wed, 19 Oct 1994 06:37:42 GMT
  3070. Organization: none
  3071.  
  3072. In article <AAC73A63966886B32@klkmac003.nada.kth.se>,
  3073. h+@nada.kth.se (Jon W{tte) wrote:
  3074.  
  3075. >>When an application freezes, dropping into MacsBug often reveals that it
  3076. >>is stuck in SyncWait.  When that happens, typing es to MacsBug or using
  3077. >>force-quit does nothing.  Is there any hope for someone with debugger
  3078. >>skills slightly below those of "Kon & Bal" to get the app out of SyncWait
  3079. >>and make it die a clean death, or should I just restart the Mac?
  3080.  
  3081. To be honest you can often get away with stepping over the SyncWait test if
  3082. you restart *immediately* you regain control.
  3083.  
  3084. In MacsBug, do a T 40. This should pop you out of any subroutines you're in
  3085. and leave you in the 2-step SyncWait loop; if not, keep doing T 40 until
  3086. you are. If you're at the TST instruction, do one more T to get to the
  3087. branch instruction. Then do PC=PC+2;G to exit the loop. 
  3088.  
  3089. You may need to repeat this process one or more times to regain control.
  3090. Once you have control, go straight to the Finder and to a Restart before
  3091. the driver can bite you again.
  3092.  
  3093. No guarantees and YMMV. However, 90% of the tine this lets be save my work
  3094. :-|
  3095.  
  3096.  
  3097.  
  3098. - -----------------------------------------------------
  3099. Richard Buckle
  3100. richardb@cocytus.demon.co.uk
  3101. Using this darned fine NewsHopper thingy.
  3102.  
  3103.  
  3104. +++++++++++++++++++++++++++
  3105.  
  3106. >From quinn@cs.uwa.edu.au (Quinn "The Eskimo!")
  3107. Date: Fri, 28 Oct 1994 10:13:36 +0800
  3108. Organization: Department of Computer Science, The University of Western Australia
  3109.  
  3110. In article <walkerj-1710942341460001@192.0.2.1>,
  3111. walkerj@math.scarolina.edu (James W. Walker) wrote:
  3112.  
  3113. >I guess I didn't make it clear in my original post, but it's not *my* code
  3114. >that gets stuck in SyncWait. It's usually Internet apps like Anarchie.
  3115.  
  3116. For reliable program (like Anarchie :) disappearing into SyncWait normally
  3117. means that your networking on your machine is stuffed up somehow.
  3118.  
  3119. To get out try this in MacsBug...
  3120.  
  3121.   sm a0+10 ffff
  3122.   g
  3123.  
  3124. What it does is set the ioResult field of the paramblock to -1, indicating
  3125. an error.  You often have to do it a *lot* of times before it comes back
  3126. and often it doesn't work at all.  But it makes you feel like you've got
  3127. control (:
  3128.  
  3129. Share and Enjoy.
  3130. --
  3131. Quinn "The Eskimo!"      "I wasn't the one who fired the heat seeking
  3132.                           population annihilator out the window!"
  3133.   Amaze your friends!  Learn some cool MacsBug or MicroBug commands today (:
  3134.  
  3135. +++++++++++++++++++++++++++
  3136.  
  3137. >From devon_hubbard@taligent.com (Devon Hubbard)
  3138. Date: Fri, 28 Oct 1994 16:20:48 GMT
  3139. Organization: Taligent, Inc.
  3140.  
  3141. In article <quinn-2810941013360001@mac168.cs.uwa.oz.au>,
  3142. quinn@cs.uwa.edu.au (Quinn "The Eskimo!") wrote:
  3143.  
  3144. >In article <walkerj-1710942341460001@192.0.2.1>,
  3145. >walkerj@math.scarolina.edu (James W. Walker) wrote:
  3146. >
  3147. >>I guess I didn't make it clear in my original post, but it's not *my* code
  3148. >>that gets stuck in SyncWait. It's usually Internet apps like Anarchie.
  3149. >
  3150. >For reliable program (like Anarchie :) disappearing into SyncWait normally
  3151. >means that your networking on your machine is stuffed up somehow.
  3152. >
  3153. >To get out try this in MacsBug...
  3154. >
  3155. >  sm a0+10 ffff
  3156. >  g
  3157. >
  3158. >What it does is set the ioResult field of the paramblock to -1, indicating
  3159. >an error.  You often have to do it a *lot* of times before it comes back
  3160. >and often it doesn't work at all.  But it makes you feel like you've got
  3161. >control (:
  3162.  
  3163. Ouch! OUCH! This is assuming that reg A0 really points to the
  3164. cntrlParamBlockRec, which I hate to say doesn't always! I recently ran
  3165. into a vSyncWait problem (on an 8100av) that lead to fingering the
  3166. offending driver by looking at the data moved off D2 and matching that as
  3167. a DCE entry with the help of Macsbug's 'drvr' dcmd.  In every case of
  3168. vSyncWait hang, a0 WAS NOT pointing to a valid paramblock so do a
  3169.  
  3170.    dm a0 cntrlparamblockrec
  3171.  
  3172. before the 'sm' and make sure it looks like a valid paramblock, or you'll
  3173. surely be rebooting thereafter.
  3174.  
  3175. dEVoN
  3176.  
  3177. - -----------------------------------------------------------------------
  3178. Devon Hubbard                                               Silicon Pilot
  3179. devon_hubbard@taligent.com                                  Taligent, Inc
  3180.  
  3181. ---------------------------
  3182.  
  3183. >From macrshap@bbn.com (Richard Shapiro)
  3184. Subject: having trouble with AEInteractWithUser & drag manager
  3185. Date: 9 Oct 1994 17:09:27 GMT
  3186. Organization: Bolt, Beranek and Newman Inc.
  3187.  
  3188. I'm in the process of adding some drag-support to an application. It's
  3189. working ok when the application is selected, so the underlying drag
  3190. management seems fine. But usually, I want to drag when another
  3191. application is selected (ie I'll be dragging from that other application).
  3192. In this case, when my app receives the drag, it needs to interact with the
  3193. user before proceeding. This is where I'm stuck. 
  3194.  
  3195. I've set the InteractionAllowed flag to kAEInteractWithLocal (the default,
  3196. I know, but I thought I'd be explicit), and I carefully call
  3197. AEInteractWithUser before attempting any interaction. I'm calling it
  3198. without a timeout (kNoTimeOut), without a notification rec (should be OK
  3199. since I have the relevant BNDL, FREF and ICN# resources defined), and with
  3200. a very simple idle procedure which essentially does nothing (since at the
  3201. moment nothing in my app cares about update or activate events). 
  3202.  
  3203. What I expected to happen was the usual flashing in the
  3204. current-application icon (on the right edge of the menubar), which would
  3205. allow me to bring my app to the front. What actually happens is...nothing:
  3206. no flashing, no process paying attention to mouse clicks, hence no way to
  3207. select my application (which has received the drop and is waiting in the
  3208. call to AEInteractWithUser) so that I can interact with it. All I can do
  3209. is cmd-opt-escape to force a quit.
  3210.  
  3211. What am I doing wrong? I'm assuming it must be one of two things: either
  3212. it's illegal to have user interaction after receiving a drop but before
  3213. acknowledging receipt; or I need to handle something in my idle function
  3214. which I'm not currently handling.
  3215.  
  3216. Any suggestions? If it matters, I'm using CW 4.5 C, and running System 7.1
  3217. on a q660av with drag extensions and the drag-ware Finder (7.1.3). The
  3218. drag flavors I'm handling at the moment are 'hfs ' and 'TEXT'.
  3219.  
  3220. Please copy followups to email -- thanks.
  3221.  
  3222. -- 
  3223. rs/macrshap@bbn.com
  3224.  
  3225. +++++++++++++++++++++++++++
  3226.  
  3227. >From Jens Alfke <jens_alfke@powertalk.apple.com>
  3228. Date: Mon, 10 Oct 1994 22:12:55 GMT
  3229. Organization: Apple Computer
  3230.  
  3231. Richard Shapiro, macrshap@bbn.com writes:
  3232. > What am I doing wrong? I'm assuming it must be one of two things: either
  3233. > it's illegal to have user interaction after receiving a drop but before
  3234. > acknowledging receipt
  3235.  
  3236. Bingo -- more specifically, it's illegal to cause a process switch while
  3237. inside a drag handler, since the drag handlers are called via a lightweight
  3238. process switch that is not compatible with the regular kind of process
  3239. switch. While you're in a drag handler, WNE is hacked to do nothing for
  3240. compatibility, but other ways to interact (such as calling AEInteractWithUser
  3241. or SetFrontProcess) will choke your machine.
  3242.  
  3243. Moral: Wait until after the drag finishes to try to interact with the user.
  3244.  
  3245. --Jens Alfke                           jens_alfke@powertalk.apple.com
  3246.                    "A man, a plan, a yam, a can of Spam ... Bananama!"
  3247.  
  3248. +++++++++++++++++++++++++++
  3249.  
  3250. >From macrshap@bbn.com (Richard Shapiro)
  3251. Date: 11 Oct 1994 01:54:10 GMT
  3252. Organization: Bolt, Beranek and Newman Inc.
  3253.  
  3254. In article <1994Oct10.221255.26429@gallant.apple.com>, Jens Alfke
  3255. <jens_alfke@powertalk.apple.com> wrote:
  3256.  
  3257. > Bingo -- more specifically, it's illegal to cause a process switch while
  3258. > inside a drag handler, since the drag handlers are called via a lightweight
  3259. > process switch that is not compatible with the regular kind of process
  3260. > switch. While you're in a drag handler, WNE is hacked to do nothing for
  3261. > compatibility, but other ways to interact (such as calling AEInteractWithUser
  3262. > or SetFrontProcess) will choke your machine.
  3263. > Moral: Wait until after the drag finishes to try to interact with the user.
  3264.  
  3265. OK, I eventually came to that conclusion myself. I guess it's good to have
  3266. it validated... 
  3267.  
  3268. Problem is, I really need user interaction to complete the processing of
  3269. the drop. So, I tried to get around it by stashing the DragReference in a
  3270. global, setting a flag, returning from the handler, and then dealing with
  3271. the stashed DragReference when I'm back in the main event loop (depending
  3272. on the flag, of course). This doesn't work either. I can interact with the
  3273. user, but it looks as though the information associated with the
  3274. DragReference vanishes once the handler is exited. At least, I can't get
  3275. CountDragItems and the like to work properly outside the handler context.
  3276. Are these supposed to work outside the handler?
  3277.  
  3278. That seems to leave me with one final option: I have to get *all* the data
  3279. out of the DragReference while I'm in the handler, stash the whole pile
  3280. somewhere, exit the handler, and process the data later. Yucch, that's
  3281. pretty awful. Is there another possibility I'm missing here?
  3282.  
  3283. For now, I "fixed" the application to run without user-interaction when it
  3284. isn't in the foreground (which can only happen as a result of a drop).
  3285. It's better than nothing, but really not what I want...
  3286.  
  3287. -- 
  3288. rs/macrshap@bbn.com
  3289.  
  3290. +++++++++++++++++++++++++++
  3291.  
  3292. >From Jens Alfke <jens_alfke@powertalk.apple.com>
  3293. Date: Tue, 11 Oct 1994 17:28:36 GMT
  3294. Organization: Apple Computer
  3295.  
  3296. Richard Shapiro, macrshap@bbn.com writes:
  3297. > That seems to leave me with one final option: I have to get *all* the data
  3298. > out of the DragReference while I'm in the handler, stash the whole pile
  3299. > somewhere, exit the handler, and process the data later. Yucch, that's
  3300. > pretty awful. Is there another possibility I'm missing here?
  3301.  
  3302. Since you can't possibly use the DragReference after the sender disposes of
  3303. it, I think this is your only option. Is it that bad? Get the data you want
  3304. to use, stash it somewhere temporary, and when you get back into your event
  3305. loop ask the user what to do with it.
  3306.  
  3307. --Jens Alfke                           jens_alfke@powertalk.apple.com
  3308.                    "A man, a plan, a yam, a can of Spam ... Bananama!"
  3309.  
  3310. +++++++++++++++++++++++++++
  3311.  
  3312. >From macrshap@bbn.com (Richard Shapiro)
  3313. Date: 11 Oct 1994 22:25:03 GMT
  3314. Organization: Bolt, Beranek and Newman Inc.
  3315.  
  3316. In article <1994Oct11.172836.17257@gallant.apple.com>, Jens Alfke
  3317. <jens_alfke@powertalk.apple.com> wrote:
  3318.  
  3319.  
  3320. > Since you can't possibly use the DragReference after the sender disposes of
  3321. > it
  3322.  
  3323. As expected.
  3324.  
  3325. > I think this is your only option. Is it that bad? Get the data you want
  3326. > to use, stash it somewhere temporary, and when you get back into your event
  3327. > loop ask the user what to do with it.
  3328.  
  3329. No, it's not as bad as I thought. In fact it's already done and the result
  3330. is cleaner than my original plan :)
  3331.  
  3332. Now on to my next drag-manager question: receiving promise-hfs drags in an
  3333. application other than the Finder. Details in another posting...
  3334.  
  3335. -- 
  3336. rs/macrshap@bbn.com
  3337.  
  3338. +++++++++++++++++++++++++++
  3339.  
  3340. >From leonardr@netcom.com (Leonard Rosenthol)
  3341. Date: Wed, 19 Oct 1994 22:01:35 GMT
  3342. Organization: Aladdin Systems, Inc.
  3343.  
  3344. In article <macrshap-1110941825500001@ipa.bbn.com>, macrshap@bbn.com
  3345. (Richard Shapiro) wrote:
  3346.  
  3347. > > I think this is your only option. Is it that bad? Get the data you want
  3348. > > to use, stash it somewhere temporary, and when you get back into your event
  3349. > > loop ask the user what to do with it.
  3350. > No, it's not as bad as I thought. In fact it's already done and the result
  3351. > is cleaner than my original plan :)
  3352.    What I've been doing in this case is to get all the info from the Drag,
  3353. and then send it back to myself in an Apple event (but NOT in sendToSelf
  3354. mode).  This works quite nicely...
  3355.  
  3356.  
  3357. Leonard
  3358. - ------------------------------------------------------------------------
  3359. Leonard Rosenthol                      Internet:       leonardr@netcom.com
  3360. Director of Advanced Technology        AppleLink:      MACgician
  3361. Aladdin Systems, Inc.                  GEnie:          MACgician
  3362.  
  3363. +++++++++++++++++++++++++++
  3364.  
  3365. >From jonpugh@netcom.com (Jon Pugh)
  3366. Date: Wed, 26 Oct 1994 07:08:53 GMT
  3367. Organization: Will hack for food
  3368.  
  3369. Leonard Rosenthol (leonardr@netcom.com) wrote:
  3370. >    What I've been doing in this case is to get all the info from the Drag,
  3371. > and then send it back to myself in an Apple event (but NOT in sendToSelf
  3372. > mode).  This works quite nicely...
  3373.  
  3374. I actually send the event twice.  Once to myself as record only, and then
  3375. again with signature addressing so that it goes through the event loop.
  3376. That way you can record the event too.
  3377.  
  3378. Jon
  3379.  
  3380.  
  3381. ---------------------------
  3382.  
  3383. End of C.S.M.P. Digest
  3384. **********************
  3385.  
  3386.  
  3387.  
  3388.